特殊需求:EF 6.x如何比较TimeSpan格式的字符串?EF Core实现方式是否和EF 6.x等同?
前言
我们知道C#中的TimeSpan对应SQL Server数据库中的Time类型,但是如果因为特殊需求数据库存储的不是Time类型,而是作为字符串,那么我们如何在查询数据时对数据库所存储的字符串类型进行比较呢?
TimeSpan类型比较
首先我们来看看正常情况下属性为TimeSpan类型进行比较的情况,给出如下实体模型。
public class TestA
{
public int Id { get; set; }
public string StrartEnd { get; set; }
public string EndTime { get; set; } public TimeSpan TimeSpanStartEnd { get; set; }
public TimeSpan TimeSpanEndTime { get; set; }
}

using (var ctx = new EfDbContext())
{
ctx.Database.Log = Console.WriteLine; var testA = new TestA()
{
StrartEnd = "10:00:00",
EndTime = "22:59:00",
TimeSpanStartEnd = new TimeSpan(, , ),
TimeSpanEndTime = new TimeSpan(, , )
}; ctx.TestAs.Add(testA);
ctx.SaveChanges();
};


如上正常流程添加数据到数据库中,接下来我们来查询数据利用TimeSpanStartEnd和TimeSpanEndTime,如下:
using (var ctx = new EfDbContext())
{
ctx.Database.Log = Console.WriteLine; var test = ctx.TestAs.Where(d => d.TimeSpanStartEnd >= DateTime.Now.TimeOfDay && DateTime.Now.TimeOfDay <= d.TimeSpanStartEnd).ToList(); };

居然不支持TimeOfDay,需要初始化值设定项,那我们接下来初始化TimeSpan看看:
using (var ctx = new EfDbContext())
{
ctx.Database.Log = Console.WriteLine; var time = new TimeSpan(, , ); var test = ctx.TestAs.Where(d => d.TimeSpanStartEnd >= time && time <= d.TimeSpanStartEnd).ToList(); };

到此我们可以下一结论:在EF 6.x中对TimeSpan进行查询比较需要初始化TimeSpan值才行,否则抛出异常。问题来了,有一位园友问我,如果数据库存储的类型不是Time,而是字符串那么我们该如何查询比较呢?当时心里第一想法明明可以存储Time,为何要搞个字符串类型,结果问其原因是特殊需求,好吧,那没办法,那我们接下来探讨一下如何,请往下看,我们利用属性StartEnd和EndTime来查询。
EF 6.x如何比较TimeSpan格式的字符串?
此时我们首先需要将数据库中的字符串即StartEnd和EndTime转换为TimeSpan然后进行过滤,如下:
using (var ctx = new EfDbContext())
{
ctx.Database.Log = Console.WriteLine; var time = new TimeSpan(, , ); var test = ctx.TestAs.Where(d => TimeSpan.Parse(d.StrartEnd) >= time && time <= TimeSpan.Parse(d.EndTime)).ToList(); };

抛出异常无法支持TimeSpan中的Parse解析,也就是说EF 6.x无法将Parse进行翻译。在EF 6.x中对日期相关操作有SqlFunctions和DbFunctions,最终经过对相关APi的尝试,我们可通过如下改造就行,不知是否有更好的办法,一个简单的过滤,其代码实在有点多,直接上代码:
using (var ctx = new EfDbContext())
{
ctx.Database.Log = Console.WriteLine; var time = new TimeSpan(, , ); var test = ctx.TestAs.Where(d => ((
DbFunctions.CreateTime(
SqlFunctions.DatePart("hh", d.StrartEnd),
SqlFunctions.DatePart("mi", d.StrartEnd),
SqlFunctions.DatePart("ss", d.StrartEnd)))
>= DbFunctions.CreateTime(
SqlFunctions.DatePart("hh", time),
SqlFunctions.DatePart("mi", time),
SqlFunctions.DatePart("ss", time)))
&&
((
DbFunctions.CreateTime(
SqlFunctions.DatePart("hh", time),
SqlFunctions.DatePart("mi", time),
SqlFunctions.DatePart("ss", time)))
<= DbFunctions.CreateTime(
SqlFunctions.DatePart("hh", d.EndTime),
SqlFunctions.DatePart("mi", d.EndTime),
SqlFunctions.DatePart("ss", d.EndTime)))
).ToList(); };


好了,到了这里算是给出了我在EF 6.x中实现的解决方案,Jeff在看待EF Core和EF 6.x习惯将二者拿来比较,看看EF Core是否真的强大,我们知道EF Core中没有SqlFunctions和DbFunctions两个APi,是不是就无法实现了呢,我们实践便知,同样是进行上述查询。
EF Core比较TimeSpan格式的字符串
using (var context = new EFCoreDbContext())
{ var test = context.TestAs.Where(d => d.TimeSpanStartEnd >= DateTime.Now.TimeOfDay && DateTime.Now.TimeOfDay <= d.TimeSpanStartEnd).ToList();
}


我们能够直接比较TimeSpan类型,此时我们完全不用初始化TimeSpan直接比较就行,从最终翻译出来的SQL来看以及我在github上向EF Core团队提交的ISSUE得出利用DaTime.Now.TimeOfDay会在客户端被评估即在内存中查询,但是在EF Core 2.1会被正确翻译,详情请见我提的ISSUE(https://github.com/aspnet/EntityFrameworkCore/issues/12187)。接下来我们再来比较字符串即StartEnd和EndTime,如下:
using (var context = new EFCoreDbContext())
{
var time = new TimeSpan(, , ); var test = context.TestAs.Where(d => TimeSpan.Parse(d.StrartEnd) >= time && time <= TimeSpan.Parse(d.EndTime)).ToList();
}


最终依然能够正常查询没有出现任何异常,相比较EF 6.x实现方式而言,代码没有那么冗长,但是依然翻译错误,无论第一种方式还是第二种方式查询在翻译成SQL时都没有添加筛选条件。
总结
在EF 6.x中对于TimeSpan类型的查询必须通过TimeSpan初始化值,否则抛出异常,如果是字符串类型的TimeSpan那么在查询时需要借助SqlFunctions和DbFunctions来实现,比较复杂,而对EF Core而言就和我们正常查询一样,没有任何异同,EF Core当前已经很稳定,还是推荐大家早早使用EF Core和.NET Core,感谢您的阅读。
特殊需求:EF 6.x如何比较TimeSpan格式的字符串?EF Core实现方式是否和EF 6.x等同?的更多相关文章
- 18.翻译系列:EF 6 Code-First 中的Seed Data(种子数据或原始测试数据)【EF 6 Code-First系列】
原文链接:https://www.entityframeworktutorial.net/code-first/seed-database-in-code-first.aspx EF 6 Code-F ...
- EF Core 一、重识 EF
重识EF EF Core 学习资料:https://docs.microsoft.com/zh-cn/ef/core/dbcontext-configuration/ 本为作为EF Core学习的开始 ...
- 【Docker】 .Net Core 3.1 webapi 集成EF Code First,使用MySql进行业务操作 、配置swagger (三)
系列目录: [Docker] CentOS7 安装 Docker 及其使用方法 ( 一 ) [Docker] 使用Docker 在阿里云 Centos7 部署 MySQL 和 Redis (二) [D ...
- 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获
项目开发中的一些注意事项以及技巧总结 1.jquery采用ajax向后端请求时,MVC框架并不能返回View的数据,也就是一般我们使用View().PartialView()等,只能返回json以 ...
- EF 之 MVC 排序,查询,分页 Sorting, Filtering, and Paging For MVC About EF
最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精 上篇博客我们学习了EF CodeFirst增删改查 ...
- .NET CORE 学习笔记之安装EF【Microsoft.EntityFrameworkCore】扩展报错
最近在学习.NET CORE ,刚开始就遇到问题了. 安装EF框架的试试就报错, 报错如下: 错误 程序包还原失败.正在回滚“XXX”的程序包更改. 找了好久的方案,网上也没搜到对应的问题和方案,然而 ...
- 十二个 ASP.NET Core 例子——1.1版本 EF MySql快速搭建
core1.0的时候搭建过一次mysql EF. 一大推问题.最近在core1.1 又重新搭了一次.简单搭建还挺快,没出现什么幺蛾子.总结下步骤 建立项目,例如ASP.NET Core1.1 WebA ...
- .NET Core 多项目工程生成EF迁移代码
错误表现 dotnet ef的官方文档针对的是单个项目的情况,即启动项目就是DbContext所在项目. 对于分层结构的解决方案如启动项目是WebApi项目,DbContext在基础设施项目,在Web ...
- 【Core】在mvc使用EF
引用DLL: 继续上一篇的内容我们来添加EF实体: 首先:工具> NuGet程序包管理器>程序包管理器控制台: Install-Package Microsoft.EntityFramew ...
随机推荐
- 新更新kb4493472导致无法正常开机
昨天陆续接到电话,说是系统更新后电脑不能正常使用,症状基本是开机到欢迎界面就出现各种各样的状况,比如鼠标能动,其他无反应;欢迎界面结束后黑屏,只有鼠标能动:开机后正常,但电脑使用很卡等等状况.因为昨天 ...
- MySQL学习(三)主备分库分表和恢复数据 --- 2019年2月
1.MySQL主备切换 readonly 设置对超级(super)权限是无效的,而用于同步更新的线程,就拥有超级权限. 建议在做主备数据库的时候,将备用数据库设置为只读.(反向用readonly来判断 ...
- ASP.NET MVC权限控制思路
在系统开发的时候一个老生常谈的权限管理问题,翻阅了很多的网络资料,但是总感觉离实际使用还有一段距离,其实权限控制无非就几个“请求.页面按钮.字段显示”, 对于前端权限就需要配合JS了, 这里主要展示我 ...
- springcloud之config配置中心-Finchley.SR2版
本篇和大家分享的是springcloud-config配置中心搭建,写到这里突然想起自己曾今开源过基于Redis发布订阅编写的一个配置中心,刚看了git星数有点少哈哈,这里顺势发个连接欢迎大侠们点赞: ...
- 【TCP协议】(1)---TCP协议详解
TCP协议 本文内容如下: 1)TCP协议概念 2)TCP头部结构和字段介绍 3)TCP流量控制 滑动窗口 4)TCP拥塞控制 ...
- Redhat 平台下 LVM 管理说明
Redhat 平台下 LVM 管理说明 LVM 是 Logical Volume Manager(逻辑卷管理器)的简写,它为主机提供了更高层次的磁盘存储管理能力.LVM 可以帮助系统管理员为应用与用 ...
- ToastUtil【简单的Toast封装类】【未自定义Toast的显示风格】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 一个简单的Toast封装类. 效果图 API = 6.0 API = 4.4.2 代码分析 实现了不管我们触发多少次Toast调用, ...
- XML的创建、解析-C语言
前言:今天在做一个小项目时,客户要求的xml,跟现在有系统要求的不一样,所以要自己重新写函数支持返回,进行简单总结,希望对大家有所帮助. 首先,使用xml函数需要链上动态库libxml2,需要在电脑上 ...
- Python编程从入门到实践笔记——操作列表
Python编程从入门到实践笔记——操作列表 #coding=utf-8 magicians = ['alice','david','carolina'] #遍历整个列表 for magician i ...
- 盘点 Python 中的那些冷知识(二)
上一篇文章分享了 Python中的那些冷知识,地址在这里 盘点 Python 中的那些冷知识(一) 今天将接着分享!! 06. 默认参数最好不为可变对象 函数的参数分三种 可变参数 默认参数 关键字参 ...