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

本文介绍如何使用Expression Tree实现在Linq中对字符串属性进行动态查询,并提供两种实现方式,一种是直接使用Expression API构造,另一种是采用Lambda表达式简化流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 原文地址:http://blog.youkuaiyun.com/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<Func<DimSite, Boolean>>(siteNoExpression, new ParameterExpression[] { dimsite });  
    15.   
    16. IQueryable<DimSite> 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<Func<DimSite, Boolean>> siteNodeExpTree =  
    2.                     site =>  
    3.                     site.SiteNo.CompareTo(txtStartSiteNo.Text) >= 0 && site.SiteNo.CompareTo(txtEndSiteNo.Text) <= 0;  
    4. IQueryable<dimsite> query = context.DimSites.Where(siteNodeExpTree);AspNetPager1.RecordCount = query.Count();</dimsite>  
    这样简练多了.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值