目录:
前言
设计(完成扩展)
实现效果
扩展设计方案
扩展后代码结构
集思广益(问题)
前言:
在上一篇文章我写了如何重建IDbCommandTreeInterceptor来实现创建人、创建时间、更新人、更新时间的统一赋值。看起来会比较复杂,有人提到了重写SaveChanges来实现,这个是很好的建议,确实会更简单些。可我依旧要坚持在IDbCommandTreeInterceptor实现,具体原因吗?
有一些系统要求对实体插入更新时,保存的创建时间、更新时间为数据库服务器时间(getdate()),关于让时间保存为数据库服务器时间一般有2种做法:
1、从数据库服务器读取返回时间对实体进行赋值。
2、在数据库创建时间上设置默认值,而更新时间则需要建立触发器。
为什么需要存为数据库服务器时间:程序执行环境系统的时间可能和数据库服务器有差异,而这种差异在很多系统可能是致命的。一些桌面端应用(运行在用户电脑),没有设计服务层、客户端直接调用EF组件访问数据库,很不凑巧,有人就遇到这种系统。
大概就是这样,如果要用我之前代码实现这个功能有两种可能性:
1、修改扩展EntityFramework.SqlServer部分代码
2、使IDbCommandTreeInterceptor、IDbCommandInterceptor两者在执行过程中建立关系,篡改DbCommand的CommandText、Parameters。
其实两种实现方式我都不推荐,我还是使用第二种方式完成了这个实现,不过实际项目不推荐这么使用。
设计:
设计实现效果:
还是使用原有的配置
扩展设计方案:
我在昨天的思维导图里提示了IGetDbExpression接口为什么要耦合到DbExpression,其实就是为了在不修改SimpleSSOCommandTreeInterceptor情况下完成这个另类功能的实现,让SimpleSSOCommandTreeInterceptor承当更少的职责。
代码结构(类型之间的依赖关系):
右上角为新增的两个类,如果扩展IntercepterGeneratedType则需要调整右上角两个类及IGetDbExpression实现。
大概就是这样,对于EF,我也有两年没怎么用了。之前一直在追求许多技术上的最佳实践,对于系统技术的复杂度可以说是恒定的,可是系统的复杂度随着业务的扩展有时候是呈指数级增长的。这两年去一些大型电商公司、制造企业了解学习他们的业务,技术相对落后,中途改造了许多庞大且设计异常糟糕的系统,问题基本都是线上的,情况就是你们IT部门大部分人每天几十个人找,总的说来这两年还是收获颇丰的。
集思广益:
之前公司有使用到网上找到的自建数据库函数fun_split,这个函数执行结果没有问题,不过更严重的就是,当@input参数字符达到一定长度,随着长度增加,执行时间可以说呈指数级别的增长。
代码:
create function fun_split(@input varchar(max),@pattern varchar())
returns @temp table(a varchar())
--实现split功能 的函数
--说明:@input,字符串,如a:b:c;@pattern,分隔标志,如 :
as
begin
declare @i int
set @input=rtrim(ltrim(@input))
set @i=charindex(@pattern,@input)
while @i>=
begin
insert @temp values(left(@input,@i-))
set @input=substring(@input,@i+,len(@input)-@i)
set @i=charindex(@pattern,@input)
end
if @input<>''
insert @temp values(@input)
return
end
如何修改调整这段代码完成优化,有兴趣的朋友可以看下,有点意思。