3

我正在使用实体框架并正在构建一个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;
}
4

2 回答 2

9

此时此处:

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

您已切换到 LINQ-to-Objects。您之后所做的任何事情(就.Include等而言)都无关紧要- 您不再编写 EF 查询。您对该序列的 LINQ-to-Objects 版本有一个薄IQueryable<T>包装器,因为它位于该行,即

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

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

如果您绝对不能生成Expression,则可以将Includeetc移到这一点之上。

于 2013-05-20T15:02:07.140 回答
3

我实际上并没有把它连接起来,所以它可能会稍微偏离,但正如 Marc 所说,你已经在 AsQueryable 处换成了 Linq to Objects。

如果您删除该调用,然后将 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;
}
于 2013-05-20T15:06:57.683 回答