EntitySet.Where(myPredicate) throws NotSupportedException

前端 未结 3 906
不知归路
不知归路 2021-01-18 15:34

EDIT: Let\'s try this again. This time I\'ve used the AdventureWorks sample database so you can all play along. This will rule out anything crazy I\'ve do

相关标签:
3条回答
  • 2021-01-18 15:55

    I'd refactor the original like this

    private bool IsYourPredicateSatisfied(Maintenance plan)
    {
      return plan.CancelDate == null && plan.UpgradeDate == null;
    }
    

    Then your Where clause is Where(m => IsYourPredicateSatisfied(m))

    0 讨论(0)
  • 2021-01-18 16:11

    Try this:

    Expression<Func<DatabaseAccess.Maintenance, bool>> activePlanPredicate = plan => plan.CancelDate == null && plan.UpgradeDate == null;
    var result = from subAccount in db.SubAccounts
             select new ServiceTicket
             {
                 MaintenancePlans = subAccount.Maintenances.Where(activePlanPredicate).Select(plan => plan.ToString()).ToArray()
                 // Set other properties...
             };
    

    I don't have VisualStudio in front of me, so that may require some tweaking. The issue you're running into is that you want to access the IQueryable extension of Where, but just having a Func<T,bool> gives you the IEnumerable extension.

    0 讨论(0)
  • 2021-01-18 16:12

    I don't fully understand the guts of Linq to Entities, but there is an Open Source (usable in proprietary software) toolkit specifically designed to help solve this problem, called LinqKit, linked off this O'Reilly-related article:

    http://www.albahari.com/nutshell/predicatebuilder.aspx

    Since I don't fully understand the guts, I'll just quote them:

    Entity Framework's query processing pipeline cannot handle invocation expressions, which is why you need to call AsExpandable on the first object in the query. By calling AsExpandable, you activate LINQKit's expression visitor class which substitutes invocation expressions with simpler constructs that Entity Framework can understand.

    Here is a direct link to LinqKit.

    And here is the type of code that this project enables:

    using LinqKit;
    
    // ...
    
    Expression<Func<Product, bool>> expression = product => product.ListPrice > 0;
    
    var result = db.ProductSubcategories
        .AsExpandable() // This is the magic that makes it all work
        .Select(
            subCategory => new
            {
                Name = subCategory.Name,
                ProductArray = subCategory.Products
                    // Products isn't IQueryable, so we must call expression.Compile
                    .Where(expression.Compile())
            })
        .First();
    
    Console.WriteLine("There are {0} products in SubCategory {1} with ListPrice > 0."
        , result.ProductArray.Count()
        , result.Name
        );
    

    The result is:

    There are 3 products in SubCategory Bib-Shorts with ListPrice > 0.

    Yay, no exception, and we can extract the predicate!

    0 讨论(0)
提交回复
热议问题