20070704 linq 查询 动态组装
http://www.yippeesoft.com

sql语句都是字符串,因此可以方便的进行组装
现在LINQ是
using (Northwind db = new Northwind(ConStr))

    &leftsign;

         IQueryable<Customer> CustomerQuery = db.Customers;

         //Append filter condition to Customer Table

         CustomerQuery = db.Customers.Where(p => p.City == "London");

如果动态组装
资料:

~~~~~~~~~~~
http://www.agilelabs.cn/blogs/woody/archive/2007/03/10/ado-net-ef-dynamic-query.aspx
核心的思路还是摒弃Lamdbas表达式(尽管他出奇的方便和紧凑),要动态的构造一棵Expression Tree,然后可以动态的增加,删除节点,最后在运行时动态编译这棵树,然后执行查询,从而得到动态结果.

Ado.net Entity Framework动态查询

    刚刚接触Ado.net vNext一段时间后,我就觉得他在动态查询方面将会有巨大用途……
    在我们现有的很多项目中,设计到很多联合查询,用户自定义查询等等动态类型的查询.例如,在一个人事系统中,想要查询某一位员工,我可能提供诸如姓名,性别,籍贯,所在组织,所属领导,工作类别,薪水…等等的查询条件,用户可以任意选择,组合查询条件.而我们通常的做法都是通过判断用户选择的条件,拼凑一段SQL语句,然后交由数据库执行(我不知道在一个纯ORM方案中怎么解决).这样做,繁琐,易出错,难调试…缺点不用再多列.

~~~~~~~~~~~~~~
8.Expression trees(表达式树)
这个原文中没有做过多的介绍,里面说还有一篇文档是专门介绍这个主题的

基本大意是对于 λ表达式
Func<int,int> f = x => x + 1; // Code

可以使用 System.Query中的一个模版类 Expression<D> 把表达式转成数据
Expression<Func<int,int>> e = x => x + 1; // Data

也就是对于 f 这个其实是一个可以运行的代码,执行 x = x+1;
对于 e, 则是一个描述代码 f 的一个数据结构

~~~~~~~~~~~~~~~~~
微软替我们实现的 Where 子句对应的扩展函数实际是如下的定义:

namespace System.Linq
&leftsign;
    public delegate TResult Func(TArg0 arg0, TArg1 arg1);
    public static class Enumerable
    &leftsign;
        public static IEnumerable Where(this IEnumerable source, Func predicate);
        public static IEnumerable Where(this IEnumerable source, Func predicate);
    &rightsign;
&rightsign;

其中红色字体的那个扩展函数,就是我们上面代码实际使用的扩展函数。

我们这个扩展函数参数:Func predicate 的定义看上面代码的绿色delegate 代码。

~~~~~~~~~~~~~~~~

启用 LINQ 的 API 用于实现具有“延迟执行”的序列运算符。延迟执行意味着在枚举结果之前不计算查询。对于 LINQ to SQL,这意味着在请求结果之前不会将查询远程传输到 SQL。这意味着,将查询分离到多条语句中并不表示会多次找到数据库。因此,在 SQL 中通常是嵌套查询,而在 LINQ 中就变成了组合查询。

SQL 缺少组合性的一个原因是,基础关系数据模型本身不是组合的。例如,表不能包含子表;换句话说,所有表都必须是平面的。因此,SQL 程序员编写其结果为平面表、适合于 SQL 数据模型的单一表达式,而不是将复杂表达式分解为更小的单元。由于 Visual Basic 基于 CLR 类型系统,因此没有限制哪些类型可以作为其他类型的组件出现。除了静态类型规则外,对可以作为其他表达式的组件出现的表达式类型没有限制。因此,不仅行、对象和 XML,而且 Active Directory、文件、注册表项等在查询源和查询结果中都是一流成员。

~~~~~~~~~~~~~~~~~~

Another way might be to use some delimiter, say backquote, to allow variables to be injected into expressions at the lexical level.

string foo = “Name”;
Expression x = c => c.`foo` + d.`foo`

Wouldnt work in anything but expressions assigned to Expression, but…

~~~~~~~~~~~~~~
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1745163&SiteID=1
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1706161&SiteID=1
http://www.albahari.com/expressions/
Dynamically building LINQ expression predicates

http://www.ayende.com/Blog/archive/7055.aspx
 Anyway, the problem with this kind of fomrs is that they are complex beasts. I have seen search forms that were two pages long, and were accompanied with a manual (just for the search form) that was bigger than the entire system specification. The real kicker here is that there isn\’t a single path that the user is going through, the system should be able to handle any combination of search terms, and ignore any that isn\’t relevant.

There is additional complexity added by the fact that this data is not sitting in the same table, actually, just from the rough data modle above, it looks like it is sitting in no less than 6 tables.
This is also the place where the Stored Procedure approach hurts the most, in my experiance.

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1706161&SiteID=1
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=97159&SiteID=1

http://blogs.msdn.com/mattwar/archive/2006/05/10/594966.aspx
 DLINQ\’s query mechanism has been generalized and available for all to use as part of System.Query.  It implements the Standard Query Operators for you using expression nodes to represent the query. Your queries can now be truly polymorphic, written over a common abstraction and translated into the target environment only when you need it to.

 http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1752078&SiteID=1
 Check out the DynamicQuery example in the LINQ samples. It allows you to write code like the following:

 

Code Snippet

var query =
    db.Customers.
    Where("City = @0 and Orders.Count >= @1", "London", 10).
    OrderBy("CompanyName").
    Select("new(CompanyName as Name, Phone)");

 

The example includes fairly extensive documentation and is really easy to incorporate in your app.

http://msdn2.microsoft.com/en-us/bb330936.aspx
C# LINQ Samples and content for Beta 1

原创文章,转载请注明: 转载自YippeeSoft开心软件

本文链接地址: 20070704 linq 查询 动态组装

历史博文

标签:,