Исходя из отличного ответа на мой предыдущий вопрос:
Метод универсального фильтра 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
}
}
);
В этом примере я хотел бы, чтобы Order 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, но та же ошибка вернулась.