关于Func <telement,bool =“”>谓词</telement,>

时间:2011-03-06 02:55:05

标签: c# linq-to-sql

//my question is here
public static Query Where<TElement>(this Query query, Func<TElement, bool> predicate) 
{
     query.sql +=" FROM Table WHERE "+ predicate+";"; 
     return query; 
} 

//Query class 
public class Query 
{
     public Query(){}
     public Query(string sql){this.sql = sql;} 
     public string sql { set; get; } 
}

//User class 
public class User 
{ 
     public int ID { get; set; } 
     public string Name { get; set; } 
} 

//example: 
User user = new User() { ID=1,Name="test"}; 
Query query = new Query(); 
query = query.Where<User>(u=>u.ID==user.ID); 
Console.WriteLine(query.sql);

运行后,结果是:

FROM Table WHERE System.Func'2[DAL.User,System.Boolean]';

但我需要的是:

FROM Table WHERE ID=1;

有人可以帮助我吗?

2 个答案:

答案 0 :(得分:3)

如果您想了解Linq to Sql如何构建SQL查询,您的第一步将是了解Expression Trees

下一步将是熟悉ExpressionVisitor,这将有助于您如何访问表达式树中的每个部分。

从那里阅读博客系列"LINQ: Building an IQueryable provider series",了解如何将表达式树解析为sql。

帖子"Where and reusable Expression tree visitor"将有助于解析如何解析谓词。

既然你不会使用IQueryable<T>.Where()而只是Expression<Func<T, bool>>,那么这些帖子中的所有内容都不会完全相关,但应该是如何将谓词表达式解析为有效的sql where子句的良好开端

希望这可以帮助你开始!

答案 1 :(得分:1)

在这里,您似乎正在尝试使您的Query类可以访问LINQ。当您参与LINQ Where子句时,您获得的谓词是函数对象,而不是字符串。我们的想法是将谓词函数应用于您枚举的每个元素,并且只返回函数返回“true”的元素。

LINQ-to-SQL查看这样的谓词中的代码,它假定它是一个表达式(例如,lambda),它可以分析并转换为SQL表达式。请记住,编译器可以将C#lambda生成到委托或表达式树(请参阅this MSDN topic),具体取决于它所在表达式中的预期类型。因此,LINQ-to-SQL正在做很多事情。换句话说,将该谓词转换为可以针对数据库引擎运行的内容。

如果您真的要使用LINQ,您可能只需要查询查询中的所有记录,然后使用谓词过滤它们,除非这代表了一个扩展问题(取决于您的应用程序的严重程度)。此外,您必须编写一个正确的Where函数,它返回一个IEnumerable对象并使用yield-return。请参阅this tutorial page(您必须向下滚动一下)或阅读Nutshell书中优秀C#中的LINQ章节。

另一方面,如果您实际上并不关心LINQ,并且此代码恰好是LINQ-y,那么只需将您的参数类型更改为string并在您想要使用的表达式周围加上引号。