`
txf2004
  • 浏览: 6873533 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

 
阅读更多

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

BinaryExpression siteNoExpression = Expression.AndAlso(
                    Expression.LessThanOrEqual(
                    Expression.Property(dimsite, propertyInfo),
                        Expression.Constant(txtStartSiteNo.Text, typeof(String))
                        ),
                    Expression.GreaterThanOrEqual(
                        Expression.Property(dimsite, propertyInfo),
                        Expression.Constant(txtEndSiteNo.Text, typeof(String)))
                    );

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

没有为类型“System.String”和“System.String”定义二进制运算符 LessThanOrEqual。

说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。 异常详细信息: System.InvalidOperationException: 没有为类型“System.String”和“System.String”定义二进制运算符 LessThanOrEqual。

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

var query = from item in context.Sites
           where item.SiteNo.ComparentTo(txtStartNo.Text)>=0

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

ParameterExpression dimsite = Expression.Parameter(typeof(DimSite), "dimsite");
var propertyInfo = typeof(DimSite).GetProperty("SiteNo");
var methodInfo = typeof(String).GetMethod("CompareTo", new Type[] { typeof(String) });//因为CompareTo有重载,所以这里指定了下参数的类型,否则会报反射异常
BinaryExpression siteNoExpression =
                    Expression.GreaterThanOrEqual(
                        Expression.Call(            
                            Expression.Property(dimsite, propertyInfo),
                            methodInfo,
                            Expression.Constant(txtStartSiteNo.Text, typeof(String))
                                ),
                        Expression.Constant(0, typeof(Int32)) //比较String.CompareTo的返回结果和0,来实现>=的效果
                        );

var expressionTree = Expression.Lambda<Func<DimSite, Boolean>>(siteNoExpression, new ParameterExpression[] { dimsite });

IQueryable<DimSite> query = context.DimSites.Where(expressionTree);
AspNetPager1.RecordCount = query.Count();

最终的SQL语句如下:

SELECT COUNT(*) AS [value] FROM [Site] AS [t0] WHERE [t0].[SiteNo] >= @p0

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

Expression<Func<DimSite, Boolean>> siteNodeExpTree =
                    site =>
                    site.SiteNo.CompareTo(txtStartSiteNo.Text) >= 0 && site.SiteNo.CompareTo(txtEndSiteNo.Text) <= 0;
IQueryable<dimsite> query = context.DimSites.Where(siteNodeExpTree);AspNetPager1.RecordCount = query.Count();</dimsite>
这样简练多了.





分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics