LINQ To SQL 之 Expression中如何定义String类型的GreaterThanOrEqual (转)

  1. 原文地址:http://blog.csdn.net/bclz_vs/article/details/6658727

    为了根据用户所选择的条件来动态构造linq查询,决定使用ExpressionTree来实现,因为在SIte表中的SiteNo是String类型的,所以界面上有个功能是用户填写SiteNo的范围,然后来查找,与是写如下语句

    [csharp]  view plain copy print ?
    1. BinaryExpression siteNoExpression = Expression.AndAlso(  
    2.                     Expression.LessThanOrEqual(  
    3.                     Expression.Property(dimsite, propertyInfo),  
    4.                         Expression.Constant(txtStartSiteNo.Text, typeof(String))  
    5.                         ),  
    6.                     Expression.GreaterThanOrEqual(  
    7.                         Expression.Property(dimsite, propertyInfo),  
    8.                         Expression.Constant(txtEndSiteNo.Text, typeof(String)))  
    9.                     );  

    与是杯具开始上演,发生异常如下:

    [html]  view plain copy print ?
    1. <span>span><h2><em>没有为类型“System.String”和“System.String”定义二进制运算符 LessThanOrEqual。em> h2><span style="font-family:Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ;"><strong> 说明: strong>执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。              
    2.   
    3. <strong> 异常详细信息: strong>System.InvalidOperationException: 没有为类型“System.String”和“System.String”定义二进制运算符 LessThanOrEqual。span>  

    而在网上搜了下,原因是因为String并没有重载操作符>=和<=,所以大多都是使用CompareTo,但都没有使用Expression,而是直接使用查询表达式来实现的,如下:

    [csharp]  view plain copy print ?
    1. var query = from item in context.Sites  
    2.            where item.SiteNo.ComparentTo(txtStartNo.Text)>=0  

    那么Expression如何来写呢,众里寻它千百度的过程就省略了,直接贴结果:

    [csharp]  view plain copy print ?
    1. ParameterExpression dimsite = Expression.Parameter(typeof(DimSite), "dimsite");  
    2. var propertyInfo = typeof(DimSite).GetProperty("SiteNo");  
    3. var methodInfo = typeof(String).GetMethod("CompareTo"new Type[] { typeof(String) });//因为CompareTo有重载,所以这里指定了下参数的类型,否则会报反射异常  
    4. BinaryExpression siteNoExpression =  
    5.                     Expression.GreaterThanOrEqual(  
    6.                         Expression.Call(              
    7.                             Expression.Property(dimsite, propertyInfo),  
    8.                             methodInfo,  
    9.                             Expression.Constant(txtStartSiteNo.Text, typeof(String))  
    10.                                 ),  
    11.                         Expression.Constant(0, typeof(Int32)) //比较String.CompareTo的返回结果和0,来实现>=的效果  
    12.                         );  
    13.   
    14. var expressionTree = Expression.Lambda>(siteNoExpression, new ParameterExpression[] { dimsite });  
    15.   
    16. IQueryable query = context.DimSites.Where(expressionTree);  
    17. AspNetPager1.RecordCount = query.Count();  

    最终的SQL语句如下:

    [csharp]  view plain copy print ?
    1. SELECT COUNT(*) AS [value] FROM [Site] AS [t0] WHERE [t0].[SiteNo] >= @p0  

    不过用Expression来写,实在太复杂了,所以被网友踩了下,换成Lanbda表达式,如下:

    [csharp]  view plain copy print ?
    1. Expression> siteNodeExpTree =  
    2.                     site =>  
    3.                     site.SiteNo.CompareTo(txtStartSiteNo.Text) >= 0 && site.SiteNo.CompareTo(txtEndSiteNo.Text) <= 0;  
    4. IQueryable query = context.DimSites.Where(siteNodeExpTree);AspNetPager1.RecordCount = query.Count();  
    这样简练多了.

你可能感兴趣的:(Linq)