В продолжение отличного ответа на мой предыдущий вопрос:
Универсальный метод фильтрации Linq Entity Framework
Сейчас я пытаюсь понять, как я могу применить что-то вроде рекурсии к моему решению.
Напомним, вместо нескольких похожих объявлений этого метода:
protected IQueryable<Database.Product> GetActiveProducts( ObjectSet<Database.Product> products ) {
var allowedStates = new string[] { "Active" , "Pending" };
return (
from product in products
where allowedStates.Contains( product.State )
&& product.Hidden == "No"
select product
);
}
Теперь у меня есть единственная реализация, которая принимает тип интерфейса (IHideable) для работы:
protected IQueryable<TEntity> GetActiveEntities<TEntity>( ObjectSet<TEntity> entities ) where TEntity : class , Database.IHideable {
var allowedStates = new string[] { "Active" , "Pending" };
return (
from entity in entities
where allowedStates.Contains( entity.State )
&& entity.Hidden == "No"
select entity
);
}
Это работает хорошо, и решение чистое и понятное (большое спасибо https://stackoverflow.com/users/263693/stephen-cleary ).
Что я пытаюсь сделать сейчас, так это применить аналогичный (или тот же?) метод к любым коллекциям EntityCollections, связанным с EntityObject, которые также реализуют IHideable.
В настоящее время я использую GetActiveEntities() следующим образом:
var products = GetActiveEntities( Entities.Products );
return (
from product in products
let latestOrder = product.Orders.FirstOrDefault(
candidateOrder => (
candidateOrder.Date == product.Orders.Max( maxOrder => maxOrder.Date )
)
)
select new Product() {
Id = product.Id ,
Name = product.Name,
LatestOrder = new Order() {
Id = latestOrder.Id ,
Amount = latestOrder.Amount,
Date = latestOrder.Date
}
}
);
В этом примере я хотел бы, чтобы коллекция Orders EntityCollection также фильтровалась с помощью GetActiveEntities(), чтобы последний возвращаемый заказ никогда не был «скрытым».
Возможно ли, чтобы все EntityCollections, реализующие IHideable, были отфильтрованы - возможно, путем применения некоторого отражения/рекурсии внутри GetActiveEntities() и вызова самого себя? Я говорю о рекурсии, потому что лучшим решением будет многоуровневый обход графа сущностей.
Этот материал растягивает мой мозг!
ОБНОВЛЕНИЕ №1 (мои комментарии перемещены сюда)
Спасибо, Стив.
Если метод принимает IQuerable, как было предложено, возникает эта ошибка:
'System.Data.Objects.DataClasses.EntityCollection<Database.Order>' does not contain a definition for 'GetActiveEntities' and no extension method 'GetActiveEntities' accepting a first argument of type 'System.Data.Objects.DataClasses.EntityCollection<Database.Order>' could be found (are you missing a using directive or an assembly reference?)
Я предполагаю, что это связано с тем, что EntityCollection не реализует IQueryable.
Я смог продвинуться дальше, создав второй метод расширения, который явно принимал EntityCollection и возвращал IEnumerable. Это скомпилировано, но во время выполнения выдало эту ошибку:
LINQ to Entities does not recognize the method 'System.Collections.Generic.IEnumerable`1[Database.Order] GetActiveEntities[Order](System.Data.Objects.DataClasses.EntityCollection`1[Database.Order])' method, and this method cannot be translated into a store expression.
Я также попытался вызвать AsQueryable() для EntityCollection и вернуть IQueryable, но вернулась та же ошибка.