应无所住,而生其心
排名
1
文章
860
粉丝
112
评论
163
net core webapi post传递参数
庸人 : 确实坑哈,我也是下班好了好几次,发现后台传递对象是可以的,但...
百度编辑器自定义模板
庸人 : 我建议换个编辑器,因为现在百度富文本已经停止维护了,用tinymec...
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

扩展ef支持with nolock。修改EF表的别名

3587人阅读 2022/8/8 18:56 总访问:5182449 评论:0 收藏:0 手机
分类: EF

可以使用继承EF的DbCommandInterceptor,然后重写里边的方法,修改生成的sql语句

代码如下

  1. public class QueryWithNoLockDbCommandInterceptor : DbCommandInterceptor
  2. {
  3. // 可以把 from [XX] as [y] 替换为 from [XX] as [y] WITH (NOLOCK)。也就是需要在后面加上WITH (NOLOCK) 其中[XX]与[y]可以是任意英文与数字的组合名称
  4. // string pattern = @"FROM\s+\[[a-zA-Z0-9_]+\]\s+AS\s+\[[a-zA-Z0-9]+\]";
  5. // 除了支持把 from [XX] as [y] 替换为 from [XX] as [y] WITH (NOLOCK)还能支持把JOIN [XX] as [y] 替换为 from [XX] as [y] WITH (NOLOCK)
  6. string pattern = @"(?:FROM|JOIN)\s+\[[a-zA-Z0-9_]+\]\s+AS\s+\[[a-zA-Z0-9]+\]";
  7. public override InterceptionResult<object> ScalarExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<object> result)
  8. {
  9. //command.CommandText = TableAliasRegex.Replace(
  10. // command.CommandText,
  11. // "$& WITH (NOLOCK)"
  12. // );
  13. //string pattern = @"FROM\s+\[[a-zA-Z0-9]+\]\s+AS\s+\[[a-zA-Z0-9]+\]";
  14. string replacement = "$& WITH (NOLOCK)";
  15. string output = Regex.Replace(command.CommandText, pattern, replacement);
  16. command.CommandText = output;
  17. //Console.WriteLine("ScalarExecuting替换后的sql:" + output);
  18. return base.ScalarExecuting(command, eventData, result);
  19. }
  20. public override Task<InterceptionResult<object>> ScalarExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<object> result,
  21. CancellationToken cancellationToken = new CancellationToken())
  22. {
  23. //command.CommandText = TableAliasRegex.Replace(
  24. // command.CommandText,
  25. // "$& WITH (NOLOCK)"
  26. // );
  27. //string pattern = @"FROM\s+\[[a-zA-Z0-9]+\]\s+AS\s+\[[a-zA-Z0-9]+\]";
  28. string replacement = "$& WITH (NOLOCK)";
  29. string output = Regex.Replace(command.CommandText, pattern, replacement);
  30. command.CommandText = output;
  31. //Console.WriteLine("ScalarExecutingAsync替换后的sql:" + output);
  32. return base.ScalarExecutingAsync(command, eventData, result, cancellationToken);
  33. }
  34. public override InterceptionResult<DbDataReader> ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result)
  35. {
  36. //command.CommandText = TableAliasRegex.Replace(
  37. // command.CommandText,
  38. // "$& WITH (NOLOCK)"
  39. // );
  40. //string pattern = @"FROM\s+\[[a-zA-Z0-9]+\]\s+AS\s+\[[a-zA-Z0-9]+\]";
  41. string replacement = "$& WITH (NOLOCK)";
  42. string output = Regex.Replace(command.CommandText, pattern, replacement);
  43. command.CommandText = output;
  44. //Console.WriteLine("ReaderExecuting替换后的sql:" + output);
  45. return result;
  46. }
  47. public override Task<InterceptionResult<DbDataReader>> ReaderExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result,
  48. CancellationToken cancellationToken = new CancellationToken())
  49. {
  50. /* command.CommandText = TableAliasRegex.Replace(
  51. command.CommandText,
  52. "$& WITH (NOLOCK)"
  53. );*/
  54. //string pattern = @"FROM\s+\[[a-zA-Z0-9]+\]\s+AS\s+\[[a-zA-Z0-9]+\]";
  55. string replacement = "$& WITH (NOLOCK)";
  56. string output = Regex.Replace(command.CommandText, pattern, replacement);
  57. command.CommandText = output;
  58. //Console.WriteLine("ReaderExecutingAsync替换后的sql:" + output);
  59. return base.ReaderExecutingAsync(command, eventData, result, cancellationToken);
  60. }
  61. }

然后在初始化ef的时候添加即可。这样就可以自动添加with nolock了。

  1. var connection = Configuration.GetConnectionString("BloggingDatabase");
  2. services.AddDbContext<CNBLOGContext>(options =>
  3. options.UseSqlServer(connection)
  4. .AddInterceptors(new QueryWithNoLockDbCommandInterceptor())
  5. );

修改EF表的别名

在EF 中,可以通过重写 sqlGenerator 类中的方法来修改表别名。下面是一个示例:

  1. public class CustomSqlGenerator : SqlServerQuerySqlGenerator
  2. {
  3. // 重写 VisitTable 方法以添加表别名和 WITH (NOLOCK) 提示
  4. protected override Expression VisitTable(TableExpression tableExpression)
  5. {
  6. var sql = base.VisitTable(tableExpression);
  7. if (!string.IsNullOrEmpty(tableExpression.Alias))
  8. {
  9. sql = new StringFragment($"{sql} AS {tableExpression.Alias}");
  10. }
  11. return new StringFragment($"{sql} WITH (NOLOCK)");
  12. }
  13. }

在这个示例中,我们创健了一个自定义的SqlGenerator 类,并重写了其中的 VisitTable方法,在这方法中,我们首先调用类的 Visitable 方法生成 SOL,然后判断当前表达式是否有别名,如果有,则添加别名; 最后添加“WITH(NOLOCK)”提示并返回结果。
要使用自走义的 sglGenerator ,需要在 DbContext 中进行配置

  1. protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
  2. {
  3. optionsBuilder.ReplaceService<ISglGenerationHelper, SqlServerSqlGenerationHelper>();
  4. optionsBuilder,ReplaceService<IQuerySqlGeneratorFactory, CustomOuerySqlGeneratorFactory>();
  5. }
  6. private class CustomQuerySglGeneratorFactory : QuerySglGeneratorFactoryBase
  7. {
  8. public CustomQuerySqlGeneratorFactory(QuerysqlGeneratorDependencies dependencies): base(dependencies)
  9. {
  10. }
  11. public override IQuerySglGenerator Create()
  12. }

欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)

评价

扩展EF自动映射需要查询的字段(表达式树Expression),动态构建返回值

Entity Framework 动态构造select表达式比如我们需要返回某些字段会采用如下的写法但是发现每次都去写select如果字段很多不...

扩展mvc实现model直接传递匿名对象

如果我们直接通过model传递匿名对象,是不行滴后台通过model传递一个匿名对象publicActionResultIndex() { returnView(ne...

根据委托和lamdba表达式扩展方法

lamdba表达式ForEach扩展方法:public static void GetForEach&lt;T&gt;(this IEnumerable&lt;T&gt; list, Action&lt;T&gt;...

表达式树+反射扩展EF实现动态排序。List动态排序

我们在显示表格的时候经常会在点击表头的时候实现排序,当然很多前端的框架都实现了当前页的页面排序,直接配置一下就行了...

推荐Visual Studio好用的扩展插件(不定时更新)

嗨咯,大家好。什么是扩展?扩展是可以允许你在 Visual Studio 中进行自定义并增强在其中的体验的附加项,通过添加新功能或...

EF扩展反射实现动态排序+表达式树

现在各种网站上的表格可以通过点击排头来实现排序例如:今天我就来一探究竟,这是怎么实现的呢?具体步骤:我通过写扩展方...

表达式树+反射+扩展方法实现动态排序效果

后台代码如下:方法1:逐个判断 --&gt;缺点:代码重复,体验感差 if(sort.ToLower()==&quot;max&quot;) { if(sortway==...

.net Core3.0在Ubuntu 16.04上面的部署(Supervisor+nginx)(扩展docker)

前 言Linux 随着Linux越来越流行,本人一个.net程序员也多次研究linux与.net的相关产品,以及中间件的使用方式。So今天给...

字符串扩展方法

获取字符串的实际长度(按单字节) publicstaticintGetRealLength(thisstringsource) { returnSystem.Text.Encoding.Defau...

验证合法性扩展方法

Email格式是否合法 publicstaticboolIsEmail(thisstringsource) { returnRegex.IsMatch(source,@&quot;^\w+((-\w+)|(\.\...

扩展markdown增加mermaid支持画图

我看网上没有什么资料,只有说怎么去用它,没有说怎么才能用它。那就自己慢慢研究在让markdown支持,要自己实现这个必须要...

c扩展方法简单介绍

可以不用继承就可以给一个类增加方法!语法: Public static class 类名 { //你想添加的扩展方法 Public static ...

list扩展方法ForEach原理(where,FirstOrDEFault同理!)

//ForEach的原理就是使用循环 //委托使用循环 publicstaticvoidMyForEach&lt;T&gt;(thisList&lt;T&gt;item,Action&lt;T...

特性扩展实体对象验证、枚举验证值是否正确

如果实体属性字段过多,几十,上百个,如果我们每个字段都去判断的话很麻,代码量很大,我们可以采用特性加枚举进行验证:1、...

Mybatis的SQL构建7 小小扩展+springboot

pom.xml的依赖,我是直接在spring.io官方下的,这样避免依赖冲突&lt;!--jdbc--&gt; &lt;dependency&gt; &lt;groupId&gt;o...

nlog扩展官方文档

https://nlog-project.org/2015/06/30/extending-nlog-is-easy.html