2009-05-14 9 views
3

À lire avant la fermeture ou la fermeture: Cette copie presque exacte d'un previous question of mine existe dans le seul but de reformuler la question précédente à la portée Linq-To-Sql. Toutes les réponses contenues dans la question précédente sont valides pour la portée Linq, mais ne sont pas valides dans la portée Linq-To-SQL.Comment refactoriser plusieurs requêtes Linq-To-Sql similaires?

Supposons que j'ai les deux suivantes requêtes LINQ to SQL Je veux factoriser:

var someValue1 = 0; 
var someValue2= 0; 
var query1 = db.TableAs.Where(a => a.TableBs.Count() > someValue1) 
       .Take(10); 
var query2 = db.TableAs.Where(a => a.TableBs.First().item1 == someValue2) 
       .Take(10); 

Notez que seuls les Où changements de paramètres. Il existe un moyen de placer la requête dans une méthode et de passer le paramètre Where en argument?

Toutes les solutions publiées dans le previous question ont été essayées et ont échoué en exécution lorsque j'ai essayé d'énumérer le résultat.

L'exception était jeté: « surcharge non prise en charge utilisée pour l'opérateur de requête" Où »

Répondre

6

Absolument. Vous écririez:

public IQueryable<A> First10(Expression<Func<A,bool>> predicate) 
{ 
    return db.TableAs.Where(predicate).Take(10); 
} 

(Cela suppose que TableA est IQueryable<A>.)

Appelez avec:

var someValue1 = 0; 
var someValue2= 0; 
var query1 = First10(a => a.TableBs.Count() > someValue1); 
var query2 = First10(a => a.TableBs.First().item1 == someValue2); 

Je crois qui fonctionnera ...

La différence entre ceci et les réponses à votre question précédente est fondamentalement que cette méthode prend Expression<Func<T,bool>> au lieu de seulement Func<T,bool> donc il finit par utiliser Queryable.Where au lieu de Enumerable.Where.

+0

Strangr, j'ai essayé les deux cas: Expression > c1 = t => vrai; Console.WriteLine (db.Table1.Where (c1) .Count()); Func c2 = t => true; Console.WriteLine (db.Table1.Where (c2) .Count()); ils m'ont donné les mêmes résultats, pas d'erreurs d'exécution. –

1

Si vous voulez vraiment la réutilisabilité, vous pouvez essayer d'écrire vos propres opérateurs. Par exemple. au lieu d'écrire à plusieurs reprises:

var query = 
Products 
    .Where(p => p.Description.Contains(description)) 
    .Where(p => p.Discontinued == discontinued); 

vous pouvez écrire des méthodes simples:

public static IEnumerable<Product> ByName(this IEnumerable<Product> products, string description) 
{ 
    return products.Where(p => p.Description.Contains(description)); 
} 


public static IEnumerable<Product> AreDiscontinued(IEnumerable<Product> products, bool isDiscontinued) 
{ 
    return products.Where(p => p.Discontinued == discontinued); 
} 

puis l'utiliser comme ceci:

var query = Products.ByName("widget").AreDiscontinued(false); 
Questions connexes