qidao123.com技术社区-IT企服评测·应用市场

标题: 关于EFCore插件API使用中踩过的坑 [打印本页]

作者: 千千梦丶琪    时间: 2025-4-22 03:34
标题: 关于EFCore插件API使用中踩过的坑
本文基于efcore8.0,参考文档
假设须要重写efcore大概特定数据库的方法的SQL转换,按上面文档及其示例代码,本例中我们大概就是提供下面几个接口的实现。
后面再说说踩过的坑(总结)!
示例
  1. public class MyMethodCallTranslator:IMethodCallTranslator
  2. {
  3.     private readonly SqlServerSqlExpressionFactory _sqlExpressionFactory;
  4.     public MyMethodCallTranslator(SqlServerSqlExpressionFactory sqlExpressionFactory)
  5.     {
  6.         _sqlExpressionFactory=sqlExpressionFactory
  7.     }
  8.     public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList<SqlExpression> arguments,IDiagnosticsLogger<DbLoggerCategory.Query> logger)
  9.     {
  10.         //你需要的转换代码,并返回你的SqlExpression
  11.         return null;
  12.     }
  13. }
  14. public class MyMethodCallTranslatorPlugin:IMethodCallTranslatorPlugin
  15. {
  16.     public IEnumerable<IMethodCallTranslator> Translators{get;}
  17.     //坑1:这里注入时不能用SqlServerSqlExpressionFactory,无法解析SqlServerSqlExpressionFactory,只能ISqlExpressionFactory注入后再强转成SqlServerSqlExpressionFactory
  18.     public MyMethodCallTranslatorPlugin(ISqlExpressionFactory sqlExpressionFactory)
  19.     {
  20.         Translators=new List<IMethodCallTranslator>()
  21.         {
  22.             new MyMethodCallTranslator((SqlServerSqlExpressionFactory)sqlExpressionFactory)
  23.         }
  24.     }
  25. }
  26. public class MyDbContextOptionsExtension:IDbContextOptionsExtension
  27. {
  28.     private DbContextOptionsExtensionInfo? _info;
  29.     public virtual void ApplyServices(IServiceCollection services)
  30.     {
  31.         //坑2:必须用new EntityFrameworkRelationalServicesBuilder(services)再添加服务,不能直接用services添加
  32.         new EntityFrameworkRelationalServicesBuilder(services)
  33.             .TryAdd<IMethodCallTranslatorPlugin, MyMethodCallTranslatorPlugin>();
  34.     }
  35.     public virtual DbContextOptionsExtensionInfo Info
  36.         => _info ??= new ExtensionInfo(this);
  37.     public virtual void Validate(IDbContextOptions options)
  38.     {
  39.     }
  40.     private sealed class ExtensionInfo(IDbContextOptionsExtension extension) : DbContextOptionsExtensionInfo(extension)
  41.     {
  42.         public override bool IsDatabaseProvider => false;
  43.         public override int GetServiceProviderHashCode() => 0;
  44.         public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo other)
  45.             => other is ExtensionInfo;
  46.         public override void PopulateDebugInfo(IDictionary<string, string> debugInfo)
  47.         {
  48.         }
  49.         public override string LogFragment => "";
  50.     }
  51. }
  52. public static class MySqlServerDbContextOptionsBuilder Extensions
  53. {
  54.     //坑3:这里要用具体数据库的...DbContextOptionsBuilder,用DbContextOptionsBuilder也行,但是就无法注入具体的ISqlExpressionFactory
  55.     //关键是SqlServerDbContextOptionsBuilder不是从DbContextOptionsBuilder继承的,看名称似乎是继承的,其实不是
  56.     public static SqlServerDbContextOptionsBuilder Use...(this SqlServerDbContextOptionsBuilder optionsBuilder)
  57.     {
  58.         var coreOptionsBuilder = ((IRelationalDbContextOptionsBuilderInfrastructure)optionsBuilder).OptionsBuilder;
  59.         var extension = coreOptionsBuilder.Options.FindExtension<MyDbContextOptionsExtension>()
  60.             ?? new MyDbContextOptionsExtension();
  61.         ((IDbContextOptionsBuilderInfrastructure)coreOptionsBuilder).AddOrUpdateExtension(extension);
  62.         return optionsBuilder;
  63.     }
  64. }
复制代码
总结

1. ISqlExpressionFactory

注入时不能用SqlServerSqlExpressionFactory,无法解析SqlServerSqlExpressionFactory,只能ISqlExpressionFactory注入后再强转成SqlServerSqlExpressionFactory
2. EntityFrameworkRelationalServicesBuilder

必须用new EntityFrameworkRelationalServicesBuilder(services)再添加服务,不能直接用services添加
3. DbContextOptionsBuilder

这里要用具体数据库的...DbContextOptionsBuilder,用DbContextOptionsBuilder也行,但是就无法注入具体的ISqlExpressionFactory
关键是SqlServerDbContextOptionsBuilder不是从DbContextOptionsBuilder继续的,看名称似乎是继续的,其实不是

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/) Powered by Discuz! X3.4