LINQ TO SQL 动态查询

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

      首先来看看案例界面

LINQ TO SQL 动态查询_第1张图片
楚旋博客园

类似上图片,在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   @p0 AND  ( [ t0 ] . [ suBigType ]   =   @p1 AND  ( [ 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 ]   =   @p0 AND  ( [ 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 。我们也可以更好的体会到扩展方法的好处和强大。

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

你可能感兴趣的:(LINQ TO SQL 动态查询)