Sto cercando di creare una funzione generica che mi aiuti a selezionare migliaia di record utilizzando LINQ to SQL da un elenco locale. SQL Server (almeno per il 2005) limita le query ai parametri 2100 e vorrei selezionare più record.LINQ Espressione per restituire Valore di proprietà?
qui sarebbe un buon esempio di utilizzo:
var some_product_numbers = new int[] { 1,2,3 ... 9999 };
Products.SelectByParameterList(some_product_numbers, p => p.ProductNumber);
Ecco il mio (non funzionante) implementazione:
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;
}
Ho visto un sacco di esempi di predicati costruzione utilizzando espressioni. In questo caso voglio solo eseguire il delegato per restituire il valore dell'attuale numero prodotto. O meglio, voglio tradurre questo nella query SQL (funziona bene in forma non generica).
So che la compilazione dell'espressione mi riporta indietro al punto uno (passando al delegato come Func) ma non sono sicuro di come passare un parametro a un'espressione "non compilata".
Grazie per il vostro aiuto!
**** EDIT: ** Vorrei chiarire ulteriormente:
Ecco un esempio di lavoro di ciò che voglio generalizzare:
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()
;
I risultati in questo codice 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)
Sarei interessato a ciò che TSQL fa, rispetto alla mia risposta InRange ... –
SELECT [t0] . [Id], ... [t0]. [Version] FROM [Refill] AS [t0] DOVE [t0]. [Id] IN (@ p0, @ p1, @ p2, @ p3, @ p4, @ p5, @ p6, @ p7, @ p8, @ p9) ... Quella query 2 volte (20/10 = 2) – kwcto
Qual è il tuo suggerimento per ** blockSize ** per ottimizzare le query utilizzando LinqToSql? O , per dirla in modo diverso, è meglio avere meno query con blocchi più grandi o più query con blocchi più piccoli? – ni5ni6