LINQ Dynamic Where - 不添加子句

时间:2009-11-30 19:41:36

标签: c# linq

我有以下代码:

public OTestTable GetTestCode(Func<TestTable, bool> whereClause)
{
    return CoreContext.TestTables.Where(whereClause).Select(TestTableMap.DataToObject).FirstOrDefault();
}

CoreContext是我的数据上下文(在基类中初始化)

我的TestTableMap如下:

public class TestTableMap
{
    public static readonly Func<TestTable, OTestTable> DataToObject = mapper =>
       new OTestTable
       {
           Code = mapper.mycode 

       };
}

然后在我的业务方法中,我有以下内容:

public OTestTable GetTestCode(string code)
{
    return QueryEngine.GetTestCode(id => id.mycode == code);
}

从我的主程序中,我使用字符串值调用GetTestCode。

当我观看SQL分析器时,我得到以下内容:

SELECT [t0].[mycode]
FROM [dbo].[TestTable] AS [t0]

它没有附加到SQL查询的where子句。如果我将where子句添加到LINQ作为var query = from DataContext.TestTable中的c,其中c.mycode ==''选择c;

它将添加where子句。

然而,当我运行我的代码时,它将返回正确的记录,但似乎我从数据库中撤回所有记录并在我的代码中过滤(这不应该发生)。

对我做错了什么想法?

由于

3 个答案:

答案 0 :(得分:3)

为了构造SQL语句,LINQ to SQL需要一个表达式树。 Func<TestTable, bool>不代表表达式树,它是一个“黑盒子”函数指针。除了在内存集合中盲目执行LINQ之外,LINQ无法做任何明智的事情。

你需要这样做:

public OTestTable GetTestCode(Expression<Func<TestTable, bool>> whereClause) {
    return CoreContext.TestTables.Where(whereClause).Select(TestTableMap.DataToObject).FirstOrDefault();
}

此代码使用Queryable.Where扩展方法进行编译,该方法接受表达式树,而不是仅接受原始委托的Enumerable.Where扩展方法。

答案 1 :(得分:2)

尝试将where子句创建为:

Expression<Func<T, bool>> whereClause

T参数是您的源类型Table<T> source

答案 2 :(得分:0)

另请参阅PredicateBuilder此处:http://www.albahari.com/nutshell/predicatebuilder.aspx

它为您提供了方便的扩展方法来预测IQueryable<T>。像这样:

var predicate = PredicateBuilder.True<Family>();
predicate = predicate.And(o => o.Birthday < new DateTime(1980, 1, 1));
                     .Or(o => o.Name.Contains("ke"));
var result = Source.Where(predicate).ToList();