我有以下代码:
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子句。
然而,当我运行我的代码时,它将返回正确的记录,但似乎我从数据库中撤回所有记录并在我的代码中过滤(这不应该发生)。
对我做错了什么想法?
由于
答案 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();