gro*_*kky 6 c# entity-framework entity-framework-core
EF Core(就像之前的 EF 一样)会自动向模型添加带有 get/set 的属性。
我使用 Fluent API,我需要记住忽略它们,这会变得乏味 - 我总是会遇到运行时错误,因为我总是忘记。
我希望 EF 仅包含我已配置的那些属性。
如何禁用此约定?
小智 6
在 ConventionSet 对象中调用 DbContext.OnModelCreating 之前,EF Core 会收集将要应用的约定,并且传递给 OnModelCreating 的 ModelBuilber 将已包含约定发现的实体和属性。
\n然而,约定不仅仅代表\xe2\x80\x98,在开始时执行一次,然后忘记它们\xe2\x80\x99 规则来确定模型,每当您使用 Fluent API 更改模型时,它们都会不断应用。如果您手动添加实体,则此时将执行发现属性等的约定,并且模型始终保持最新。
\nConventionSet 对象定义了 \xe2\x80\x98events\xe2\x80\x99 的列表,如 \xe2\x80\x98 添加的实体类型\xe2\x80\x99,以及每个事件要执行的约定。
\n其中一个事件是 \xe2\x80\x98ModelInitialized\xe2\x80\x99 ,它在开始时运行,以通过 DbSetFindingConvention 最初识别实体。然而,此约定找到的每个实体类型都会触发“事件”EntyTypeAddedConventions,然后该事件将识别实体上的属性等。如果您只是抑制 DbSetFindingConvention,则在手动将实体类型添加到模型后,您仍然会自动获取属性。
\n为了抑制属性生成,您还需要从 EntyTypeAddedConventions 中删除 PropertyDiscoveryConvention。
\n删除所有约定可能不是一个好主意,因为您需要手动完成所有操作,这是一项乏味的工作。但是,如果您很好地了解想要摆脱哪些自动化以及哪个约定的作用,您可以有选择地删除其中一些。
\n要抑制约定,您可以交换 \xe2\x80\x93 数据库提供程序特定的!!!\xe2\x80\x93 ConventionSetBuilder 服务实现。
\npublic class CustomSqlServerConventionSetBuilder : SqlServerConventionSetBuilder {\n\n //See also notes in CustomRuntimeConventionSetBuilder\n\n\n public CustomSqlServerConventionSetBuilder([NotNullAttribute] ProviderConventionSetBuilderDependencies dependencies, [NotNullAttribute] RelationalConventionSetBuilderDependencies relationalDependencies, [NotNullAttribute] ISqlGenerationHelper sqlGenerationHelper)\n : base(dependencies, relationalDependencies, sqlGenerationHelper) {\n }\n\n public override ConventionSet CreateConventionSet() {\n ConventionSet cs = base.CreateConventionSet();\n //Do not find entity types automatically\n DbSetFindingConvention dbSetFindingConvention = cs.ModelInitializedConventions.OfType<DbSetFindingConvention>().FirstOrDefault();\n if (dbSetFindingConvention != null) {\n cs.ModelInitializedConventions.Remove(dbSetFindingConvention);\n }\n //Do not find properties automatically\n PropertyDiscoveryConvention propertyDiscoveryConvention = cs.EntityTypeAddedConventions.OfType<PropertyDiscoveryConvention>().FirstOrDefault();\n if (propertyDiscoveryConvention != null) {\n cs.EntityTypeAddedConventions.Remove(propertyDiscoveryConvention);\n }\n propertyDiscoveryConvention = cs.EntityTypeBaseTypeChangedConventions.OfType<PropertyDiscoveryConvention>().FirstOrDefault();\n if (propertyDiscoveryConvention != null) {\n cs.EntityTypeBaseTypeChangedConventions.Remove(propertyDiscoveryConvention);\n }\n\n return cs;\n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n替换 DbContext 类中 DI 服务的默认实现(例如):
\nprotected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { \n optionsBuilder.ReplaceService<Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure.IProviderConventionSetBuilder, TechnicalUtilities.CustomSqlServerConventionSetBuilder>();\n \n }\nRun Code Online (Sandbox Code Playgroud)\n或者,如果您想避免使此覆盖数据库提供程序特定,您还可以子类化 RuntimeConventionSetBuilder,覆盖 CreateConventionSet 方法,并将其注册到服务 IConventionSetBuilder。但该界面将来更有可能发生变化。
\n可以在此处找到约定的实现:\n https://github.com/dotnet/efcore/blob/main/src/EFCore/Metadata/Conventions/ \n可以在此处找到文档:\n https:// learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.metadata.conventions?view=efcore-5.0
\n您应该检查特定约定实现了哪些“事件”,如果应抑制该约定,则通常应将其从每个“事件”中删除。
\n这对于 EF Core 5.0 有效,在之前的版本中可能有所不同。您也可以查看https://github.com/dotnet/efcore/issues/5737#issuecomment-225724598
\n| 归档时间: |
|
| 查看次数: |
1717 次 |
| 最近记录: |