动态构建的谓词不能按预期工作

时间:2015-08-21 19:54:10

标签: c# entity-framework predicate

我的一个函数是使用谓词定义查询来搜索基于EF的数据库中的元素。它使用param int[] paymentsIds,因为它可以使用可变数量的参数。所以我不得不动态构造谓词。我有2个代码:一个静态(代码2)和第二个“几乎动态的静态参数(代码1)”。对我来说,他们都应该工作,但只有静态代码工作(代码2)。为什么动态构造的谓词不起作用?

带有标记的方法代码,其中代码为1&代码2开始和结束:

public IEnumerable<MwbePayment> FindPaymentByIds(int userId, params int[] ids)
    {
        //code 1 starts
        ids = new int[] { 53, 54, 55 };
        //prepare predicate dynamically
        Expression<Func<MwbePayment, bool>> innerPredicate = PredicateBuilder.False<MwbePayment>();
        foreach (int id in ids)
        {
            int tempInt = id;
            innerPredicate = innerPredicate.Or(x => x.Id == tempInt);
        }

        Expression<Func<MwbePayment, bool>> outerPredicate = PredicateBuilder.And(innerPredicate, x => x.UserData.Id == userId);

        Debug.WriteLine("outerPredicate body = {0}", outerPredicate );
        IQueryable<MwbePayment> query = DbSet.AsNoTracking().Where(outerPredicate );

        //code 1 ends

        /*
        //code 2 starts
        Expression<Func<MwbePayment, bool>> innerPredicate2 = x => (x.Id == 53 || x.Id == 54 || x.Id == 55) && x.User.Id == userId;
        Debug.WriteLine("innerPredicate2 body = {0}", innerPredicate2);
        IQueryable<MwbePayment> query = DbSet.AsNoTracking().Where(innerPredicate2);
        //code 2 ends
        */

        return query.AsEnumerable();
    }

打印到Debug.Writeline的代码1的谓词:

f => (((False OrElse Invoke(x => (x.Id == value(MobileWallet.DAL.MwbePaymentRepository+<>c__DisplayClassc).tempInt), f)) OrElse Invoke(x => (x.Id == value(MobileWallet.DAL.MwbePaymentRepository+<>c__DisplayClassc).tempInt), f)) OrElse Invoke(x => (x.Id == value(MobileWallet.DAL.MwbePaymentRepository+<>c__DisplayClassc).tempInt), f))

打印到Debug.Writeline的代码2的谓词:

x =&gt; (((x.Id == 53)OrElse(x.Id == 54))OrElse(x.Id == 55))

1 个答案:

答案 0 :(得分:2)

您不需要求助于复杂的谓词构建器,此查询归结为一个相当简单的查询:

return DbSet.Where(x => ids.Contains(x.Id) && x.UserData.Id == userId);

但是要回答你的问题,你的代码中会有一个小错字。包含Where子句的行使用的是innerPredicate而不是outerPredicate,因此应该是:

IQueryable<MwbePayment> query = DbSet.AsNoTracking().Where(outerPredicate);