Я пытаюсь создать универсальную функцию, которая поможет мне выбирать тысячи записей, используя LINQ to SQL, из локального списка. SQL Server (как минимум 2005) ограничивает количество запросов до 2100 параметров, и я хотел бы выбрать больше записей, чем это.
Вот хороший пример использования:
var some_product_numbers = new int[] { 1,2,3 ... 9999 };
Products.SelectByParameterList(some_product_numbers, p => p.ProductNumber);
Вот моя (нерабочая) реализация:
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;
}
Я видел множество примеров построения предикатов с использованием выражений. В этом случае я только хочу выполнить делегат, чтобы вернуть значение текущего ProductNumber. Или, скорее, я хочу перевести это в запрос SQL (он отлично работает в неуниверсальной форме).
Я знаю, что компиляция выражения просто возвращает меня на круги своя (передавая делегат как Func), но я не уверен, как передать параметр в "некомпилированное" выражение.
Спасибо за вашу помощь!
**** РЕДАКТИРОВАТЬ: ** Позвольте мне уточнить далее:
Вот рабочий пример того, что я хочу обобщить:
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()
;
Результаты в этом коде 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)