[英]Linq Entity Framework — can I use a recursive 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 )。
我現在想要做的是將類似(或相同?)方法應用於與EntityObject相關聯的任何EntityCollection,這些方法也恰好實現了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()進行過濾,以使返回的最新訂單永遠不會成為“隱藏”訂單。
是否可以將實現IHideable的所有EntityCollections過濾掉-可能是通過在GetActiveEntities()內部應用一些反射/遞歸並調用自身來實現的? 我之所以說遞歸,是因為最好的解決方案將遍歷實體圖的多個層次。
這些東西在拉動我的大腦!
更新#1(將我的評論移至此處)
謝謝Steve。
使方法接受建議的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.
我也嘗試在EntityCollection上調用AsQueryable()並返回IQueryable,但是又出現了相同的錯誤。
編輯為使用ObjectSet而不是EntityCollection
我建議使用我的解決方案,但作為擴展方法,可以將其應用於任何查詢:
public static IQueryable<TEntity> WhereActive<TEntity>(
this IQueryable<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
);
}
然后可以這樣使用:
var products = Entities.Products.WhereActive();
return (
from product in products
let latestOrder = (
from order in Entities.Orders.WhereActive()
where order.ProductId == product.Id
orderby candidateOrder.Date descending
select order).FirstOrDefault()
select new Product()
{
Id = product.Id,
Name = product.Name,
LatestOrder = new Order()
{
Id = latestOrder.Id,
Amount = latestOrder.Amount,
Date = latestOrder.Date
}
}
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.