簡體   English   中英

Linq實體框架-我可以使用遞歸方法嗎?

[英]Linq Entity Framework — can I use a recursive method?

接下來是對我之前的問題的出色回答:

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 )。

我現在想要做的是將類似(或相同?)方法應用於與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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM