神刀安全网

EF(Linq)框架使用过程中的小技巧汇总

这篇博客总结本人在实际项目中遇到的一些关于EF或者Linq的问题,作为以后复习的笔记或者供后来人参考(遇到问题便更新)。

技巧1: DbFunctions.TruncateTime()的使用

有没有遇到做这样的错误:

  • LINQ to Entities does not recognize the method ‘System.String ToShortDateString()’ method, and this method cannot be translated into a store expression.【LINQ to Entities不能识别‘System.String ToShortDateString()’方法】
  • System.NotSupportedException: The specified type member ‘Date’ is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.【LINQ to Entities不支持类型成员‘Date’,仅支持初始化器,实体成员和实体导航属性】
var query = from order in _orderRepository.GetAll()                 .Where(o => o.OrderType == OrderType.LineSold)                 .WhereIf(input.OrderDate!=DateTime.MinValue,o=>o.OrderDate.Date==input.OrderDate.Date)                 .WhereIf(!string.IsNullOrEmpty(input.OrderNo),o=>o.OrderNo==input.OrderNo||o.OrderNo.EndsWith(input.OrderNo))                 .WhereIf(input.Status!=-1,o=>o.Status==input.Status)     join device in _deviceRepository.GetAll()             .WhereIf(!string.IsNullOrEmpty(input.Code),d=>d.Code==input.Code) on order.TerminalID equals device.Id     join trans in _transDetailRepository.GetAll()             .WhereIf(!string.IsNullOrEmpty(input.PayOrderNo),t=>t.PayOrderNo==input.PayOrderNo||t.PayOrderNo.EndsWith(input.PayOrderNo))             on order.OrderNo equals trans.OrderNo into leftJoinResults     from leftJoinResult in leftJoinResults.DefaultIfEmpty( )      select new LineSoldOrderOutput     {         Code = device.Code,         Id = order.Id,         Amount = order.PayFee,         OrderDate = order.OrderDate,         OrderNo = order.OrderNo,         PayOrderNo = leftJoinResult.PayOrderNo??"还没产生支付方订单号",         Status = order.Status     };  

为啥有这种需求?

因为数据库中的DateTime类型都是以 2016-03-11 11:25:59 这种形式保存的,而我在客户端查询数据时,只要传入日期就行,不需要传入时间部分,所以必须把时间部分咔嚓掉(剪掉)。

正如上面的代码第三行,一开始是那么写的,结果报上面的第二种错误。

第二次改成了 .WhereIf(input.OrderDate!=DateTime.MinValue,o=>o.OrderDate.ToShortDateString()==input.OrderDate.ToShortDateString()) ,结果报上面的第一种错误。

解决办法

.WhereIf(input.OrderDate!=DateTime.MinValue,o=>DbFunctions.TruncateTime(o.OrderDate) 【我用的是EF6,Truncate,翻译为 截断 ,该函数顾名思义也就是把时间部分去掉,只保留日期部分】

EF6以前你可能需要用 EntityFunctions.TruncateTime(p.date) == dateWithoutTime

其他重点

我上面的代码还有使用linq进行三张表的连接,更重要的是,前两张表是内连接,之后再进行左连接。不熟悉linq语法的可以学习一下。

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » EF(Linq)框架使用过程中的小技巧汇总

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
分享按钮