J'essaie de créer une fonction générique pour m'aider à sélectionner des milliers d'enregistrements en utilisant LINQ to SQL à partir d'une liste locale. SQL Server (2005 au moins) limite les requêtes à 2100 paramètres et j'aimerais sélectionner plus d'enregistrements que cela.LINQ Expression à renvoyer Valeur de la propriété?
ici serait un bon exemple d'utilisation:
var some_product_numbers = new int[] { 1,2,3 ... 9999 };
Products.SelectByParameterList(some_product_numbers, p => p.ProductNumber);
Voici mon (non travail) mise en œuvre:
public static IEnumerable<T> SelectByParameterList<T, PropertyType>(Table<T> items,
IEnumerable<PropertyType> parameterList, Expression<Func<T, PropertyType>> property) where T : class
{
var groups = parameterList
.Select((Parameter, index) =>
new
{
GroupID = index/2000, //2000 parameters per request
Parameter
}
)
.GroupBy(x => x.GroupID)
.AsEnumerable();
var results = groups
.Select(g => new { Group = g, Parameters = g.Select(x => x.Parameter) })
.SelectMany(g =>
/* THIS PART FAILS MISERABLY */
items.Where(item => g.Parameters.Contains(property.Compile()(item)))
);
return results;
}
J'ai vu beaucoup d'exemples de prédicats de construction en utilisant des expressions. Dans ce cas, je veux seulement exécuter le délégué pour retourner la valeur du ProductNumber actuel. Ou plutôt, je veux traduire cela dans la requête SQL (ça marche bien sous une forme non générique).
Je sais que la compilation de l'expression me ramène juste à la case départ (passant dans le délégué comme Func) mais je ne suis pas sûr de savoir comment passer un paramètre à une expression "non compilée".
Merci pour votre aide!
**** EDIT: ** Permettez-moi de préciser encore:
Voici un exemple concret de ce que je veux généraliser:
var local_refill_ids = Refills.Select(r => r.Id).Take(20).ToArray();
var groups = local_refill_ids
.Select((Parameter, index) =>
new
{
GroupID = index/5, //5 parameters per request
Parameter
}
)
.GroupBy(x => x.GroupID)
.AsEnumerable();
var results = groups
.Select(g => new { Group = g, Parameters = g.Select(x => x.Parameter) })
.SelectMany(g =>
Refills.Where(r => g.Parameters.Contains(r.Id))
)
.ToArray()
;
résultats dans ce code SQL:
SELECT [t0].[Id], ... [t0].[Version]
FROM [Refill] AS [t0]
WHERE [t0].[Id] IN (@p0, @p1, @p2, @p3, @p4)
... That query 4 more times (20/5 = 4)
Je serais intéressé par ce que le TSQL pour cela, par rapport à ma réponse InRange ... –
SELECT [t0] . [Id], ... [t0]. [Version] DE [Recharge] AS [t0] OERE [t0]. [Id] IN (@ p0, @ p1, @ p2, @ p3, @ p4, @ p5, @ p6, @ p7, @ p8, @ p9) ... Cette requête 2times (20/10 = 2) – kwcto
Quelle est votre suggestion pour ** blockSize ** afin d'optimiser les requêtes en utilisant LinqToSql? Pour le dire autrement, est-il préférable d'avoir moins de requêtes avec des blocs plus grands, ou plus de requêtes avec des blocs plus petits? – ni5ni6