2010-07-12 57 views
0

從出色答卷下面就我剛纔的問題:Linq實體框架 - 我可以使用遞歸方法嗎?

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()過濾,從而使最新的順序返回永遠是「隱藏」一個。

是否有可能通過在GetActiveEntities()內部應用一些反射/遞歸併調用自己來實現IHideable的所有EntityCollections過濾?我說遞歸是因爲最好的解決方案會通過實體圖深入多個層次。

這東西正在伸展我的大腦!

更新#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. 

我也試過在EntityCollection調用AsQueryable已()並返回IQueryable的,但同樣的錯誤回來。

回答

2

被修改爲使用對象集代替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 
     } 
    } 
); 
+0

感謝您的回覆Stephen。實際上,我今天早些時候將該方法重構爲擴展方法,但不想陷入這個例子,因此使用了方法調用。很高興知道這是正確的舉措 - 大部分C#語言功能對我來說都是新手。 – FantasticJamieBurns 2010-07-12 19:16:16

+0

謝謝史蒂夫,我已將我的意見轉移到問題區域以便閱讀...... – FantasticJamieBurns 2010-07-12 19:30:52

+0

您是對的:'EntityCollection'不實施'IQueryable'。我更新了我的答案,使用'Entities.Orders'而不是'product.Orders',它應該可以工作。 (我也改變了'latestOrder'計算以使用'orderby')。 – 2010-07-12 19:43:36

相關問題