Вслед за отличный ответ на мой предыдущий вопрос:Linq Entity Framework - могу ли я использовать рекурсивный метод?
Linq Entity Framework generic filter method
Я сейчас пытаюсь понять, как я могу применить что-то вроде рекурсии к моему решению.
Напомним, что вместо нескольких подобных заявлений этого метода:
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
}
}
);
В этом примере я хотел бы иметь заказы EntityCollection также фильтровать по GetActiveEntities(), так что последний заказ возвращается не может быть «скрытый».
Возможно ли, что все EntityCollections, реализующие IHideable, будут отфильтрованы - возможно, применив некоторое отражение/рекурсию внутри GetActiveEntities() и вызвав себя? Я говорю рекурсию, потому что лучшее решение будет проходить несколько уровней, проходящих через граф объектов.
Этот материал растягивает мой мозг!
UPDATE # 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, но та же ошибка вернулась.
Спасибо за ответ Стивен. Я на самом деле реорганизовал метод в метод расширения ранее сегодня, но не хотел увязывать этот пример, поэтому использовал вызов метода. Приятно знать, что это был правильный ход - большая часть функциональных возможностей языка C# для меня нова. – FantasticJamieBurns
Спасибо Стив, я переместил свои комментарии в область вопросов, чтобы упростить чтение ... – FantasticJamieBurns
Вы правы: 'EntityCollection' не реализует' IQueryable'. Я обновил свой ответ, чтобы использовать 'Entities.Orders', а не' product.Orders', который должен работать. (Я также изменил расчет 'lastOrder', чтобы использовать' orderby'). –