Я использовал эти распространенные EntityObjectFilters как способ «труб и фильтров» для запроса из коллекции определенного элемента с идентификатором:
public static class EntityObjectFilters
{
public static T WithID<T>(this IQueryable<T> qry,
int ID) where T : IEntityObject
{
return qry.SingleOrDefault<T>(item => item.ID == ID);
}
public static T WithID<T>(this IList<T> list,
int ID) where T : IEntityObject
{
return list.SingleOrDefault<T>(item => item.ID == ID);
}
}
.. но я удивился: «Могу ли я сделать это проще, просто создав расширение для всех IEnumerable<T>
типов»?
Итак, я придумал это:
public static class EntityObjectFilters
{
public static T WithID<T>(this IEnumerable<T> qry,
int ID) where T : IEntityObject
{
return qry.SingleOrDefault<T>(item => item.ID == ID);
}
}
Теперь, когда этот появляется для получения того же результата, я хочу знать, что при применении к IQueryable<T>
s дерево выражений будет передано в LinqToSql для оценки в виде кода SQL или будет ли мой qry
сначала оцениваться целиком, а затем повторяться с Func
s?
Я подозреваю, что (согласно ответу Ричарда ) последнее будет правдой, что, очевидно, является тем, чего я не хочу. Я хочу тот же результат, но дополнительное преимущество отложенного выполнения SQL для IQueryable<T>
с. Может ли кто-нибудь подтвердить для меня, что на самом деле произойдет, и дать простое объяснение того, как это будет работать?
РЕДАКТИРОВАТЬ:
Решение, с которым я пошел
public static T WithID<T>(this IEnumerable<T> qry,
int ID) where T : DomainBase
{
if (qry is IQueryable<T>)
return ((IQueryable<T>)qry).SingleOrDefault<T>(item => item.ID == ID);
else
return qry.SingleOrDefault<T>(item => item.ID == ID);
}