将Func传递到Where并使用IQueryable

时间:2013-05-20 14:57:10

标签: c# .net entity-framework

我正在使用Entity Framework并正在构建IQueryable<T>

IQueryable<Message> query = db.Messages;

query = query.OrderByDescending(m => m.Created);
query = query.Where(m => m.Deleted == false);

if (lastTime != null)
    query = query.Where(m => m.Created < lastTime);

var func = ExpressionHelper.GetPredicate(stream);

query = query.Where(func).AsQueryable; *** ISSUE HERE?? ***

query = query.Skip(skip)
          .Take(count)
          .Include(m => m.Tags)
          .Include(m => m.Properties);

var results = query.ToList();

问题是标签和属性未填入最终列表。

我认为它与我传入的Func<>有关,并且相信在使用AsQueryable之后它虽然使用IQueryable但它不代表Func<>或不再连接到数据库。

有没有办法填充标签和属性?

我不确定让Expression<Func<>>成为Expression<Func<>>是否会有所帮助,如果有,可以将下面的内容转换为public static Func<Message, bool> GetPredicate(string expression) { Func<Message, bool> result = null; try { ParameterExpression parameter = Expression.Parameter(typeof(Classes.Message), "Message"); var lambda = DynamicExpression.ParseLambda(new[] { parameter }, null, expression); result = lambda.Compile() as Func<Message, bool>; } catch (Exception e) { Log.Fatal(e); } return result; }

更新

{{1}}

2 个答案:

答案 0 :(得分:7)

此时此处:

query.Where(func) // where func is Func<...>

您已切换到LINQ到对象。你做的任何事情(根据.Include等)是无关紧要的 - 你不再编写EF查询。对于序列的LINQ-to-Objects版本,你有一个瘦IQueryable<T>包装器,就像它在那一行那样,即

query = query.Where(func).AsQueryable(); // this is just a thing veneer over L2O

切换到Expression<Func<...>>可能有所帮助。

如果你绝对肯定无法生成Expression,那么你可以将Include移到之上。

答案 1 :(得分:2)

我实际上没有把它连接起来所以它可能稍微关闭了,但是正如Marc所说你已经在AsQueryable中将Linq换成了对象。

如果删除该调用,然后将GetPredicate切换到下面,它应该可以正常工作。它是相同的,除了我们不需要编译lambda,这将在查询到达实体框架时发生。

public static Expression<Func<Message, bool>> GetPredicate(string expression)
{
    Expression<Func<Message, bool>> result = null;

    try
    {
        ParameterExpression parameter = Expression.Parameter(typeof(Classes.Message), "Message");
        var lambda = DynamicExpression.ParseLambda(new[] { parameter }, null, expression);
        result = (Expression<Func<Message, bool>>)lambda;
    }
    catch (Exception e)
    {
        Log.Fatal(e);
    }

    return result;
}