LINQ TO SQL 动态查询

转载:http://www.cnblogs.com/eflylab/archive/2009/07/16/1525173.html

有时候我们的应用程序可能会提供一个用户界面,用户可以使用该用户界面指定一个或多个谓词来筛选数据。这对于刚刚接触LINQ TO SQL的朋友来说可能比较费劲。相对会怀念SQL下的strWhere拼接的方便形式。其实这种情况下LINQ也有比较简单的实现方式。

      首先来看看案例界面

楚旋博客园

类似上图片,在LINQ TO SQL下实现动态条件查询!

本文提供二种方法:

复制代码
 //此方法是 “一步步” 缩小 查询 的范围        private void MethodA()         {             using (NewCnqsqDataContext db = new NewCnqsqDataContext())             {                 //记录Linq to sql 最终执行的SQL语句                StreamWriter sw = new StreamWriter("c:/testsql.txt");                 db.Log = sw;
                
//查询所有                var query = from obj in db.QwqSubject orderby obj.suCreateDate descending select obj;                 if (ddlSuType.SelectedValue != "-1")                 {                     //如果选择 增加 查询贴吧类型                    query = from obj in query where obj.suType == Convert.ToInt32(ddlSuType.SelectedValue) orderby obj.suCreateDate descending select obj;                 }                 if (ddlBigType.SelectedValue != "-1")                 {                     //如果选择 增加 查询帖子的类别                    query = from obj in query where obj.suBigType == ddlBigType.SelectedValue orderby obj.suCreateDate descending select obj;                 }                 if (txtSearch.Text.Trim() != "")                 {                     //如果有关键字 增加  查询标题中是否含有                    query = from obj in query where obj.suTitle.Contains(txtSearch.Text.Trim()) orderby obj.suCreateDate descending select obj;                 }                 //由于LINQ TO SQL采用延迟加载技术 所以不用担心 上面代码 在查询 4次 最终“聪明”的LINQ 会只执行一条SQL语句                GridView1.DataSource = query;                 GridView1.DataBind();                 sw.Flush();                 sw.Close();             }         }
复制代码

最终执行的SQL语句为:

复制代码
SELECT [t0].[suId][t0].[suTitle][t0].[suUserId][t0].[suType][t0].[suCreateDate][t0].[suContent][t0].[suState][t0].[suInfo1][t0].[suInfo2][t0].[suBigType][t0].[suOrderBy][t0].[fromIp]FROM [dbo].[QwqSubject] AS [t0]WHERE ([t0].[suTitle] LIKE @p0AND ([t0].[suBigType] = @p1AND ([t0].[suType] = @p2) ORDER BY [t0].[suCreateDate] DESC-- @p0: Input NVarChar (Size = 4; Prec = 0; Scale = 0) [%写真%] -- @p1: Input NVarChar (Size = 2; Prec = 0; Scale = 0) [随便贴吧] -- @p2: Input Int (Size = 0; Prec = 0; Scale = 0) [1] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1
复制代码

 

方法2

复制代码
//动态LINQ 类似 “反射” 将字符串 按最终 LINQ TO SQL 的语义 执行        private void MethodB()         {             using (NewCnqsqDataContext db = new NewCnqsqDataContext())             {                 //记录Linq to sql 最终执行的SQL语句                StreamWriter sw = new StreamWriter("c:/testsql2.txt");                 db.Log = sw;                 string strWhere = "1==1 ";//默认查询所有                 if (ddlSuType.SelectedValue != "-1")                 {                     strWhere += " and suType==" + Convert.ToInt32(ddlSuType.SelectedValue) + "";                 }                 if (ddlBigType.SelectedValue != "-1")                 {                     strWhere += " and suBigType==\"" + ddlBigType.SelectedValue + "\"";                 }                 if (txtSearch.Text.Trim() != "")                 {                     strWhere += " and suTitle.Contains(\"" + txtSearch.Text.Trim() + "\")";                 }
                
//显示排序 以及 查寻指定列 可以直接 db.QwqSubject.Where(strWhere) 取结果 如果不需要排序 和 指定列                var query = db.QwqSubject.Where(strWhere).OrderBy("suCreateDate desc,suBigType asc").Select("New(suType, suBigType,suTitle)");                                  GridView1.DataSource = query;                 GridView1.DataBind();                 sw.Flush();                 sw.Close();             }         }
复制代码

方法2生成的SQL语句为:

复制代码
SELECT [t0].[suType][t0].[suBigType][t0].[suTitle]FROM [dbo].[QwqSubject] AS [t0]WHERE ([t0].[suType] = @p0AND ([t0].[suTitle] LIKE @p1) ORDER BY [t0].[suCreateDate] DESC[t0].[suBigType]-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [2] -- @p1: Input NVarChar (Size = 4; Prec = 0; Scale = 0) [%写真%] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1
复制代码

注意:要使上述方法编译通过,需要引入using System.Linq.Dynamic;命名空间。该命名空间系统中默认没有,但微软在VS2008安装文件夹中可以找到

C:\Program Files\Microsoft Visual Studio 9.0\Samples\2052\CSharpSamples.zip 解压出来后在LinqSamples可以找到。如果找不到该压缩包,可以从微软官方http://code.msdn.microsoft.com/csharpsamples/Release/ProjectReleases.aspx?ReleaseId=8进行下载

官方提供的Dynamic.cs采用了C#新特性 扩展了DynamicQueryable的固有函数。使得系统中原有的where,orderby等可以直接将string作为参数,然后再把传入的字符串进行分析,最终通过System.Linq.Expressions.Expression来实现动态Lambda 。我们也可以更好的体会到扩展方法的好处和强大。

      另外网上还有相对“正统”的解决方法 使用表达式树来解决。但我个人认为这种方式显得太不友好。

posted on 2013-12-02 20:24  太极球  阅读(166)  评论(0)    收藏  举报

导航