C# 禁用EF Core';s包括所有财产的惯例
EF Core(与之前的EF一样)会自动添加到模型中 我使用Fluent API,我需要记住忽略它们,这会变得很乏味——我总是会遇到运行时错误,因为我总是忘记 我希望EF只包括我配置的那些属性C# 禁用EF Core';s包括所有财产的惯例,c#,entity-framework,entity-framework-core,C#,Entity Framework,Entity Framework Core,EF Core(与之前的EF一样)会自动添加到模型中 我使用Fluent API,我需要记住忽略它们,这会变得很乏味——我总是会遇到运行时错误,因为我总是忘记 我希望EF只包括我配置的那些属性 如何禁用此约定?在ConventionSet对象中调用DbContext.OnModelCreating之前,EF Core将收集将应用的约定,传递给OnModelCreating的ModelBuilber将已经包含由约定发现的实体和属性 然而,约定并不只是代表“一开始就做一次,然后忘记它们”规则来确定模
如何禁用此约定?在ConventionSet对象中调用DbContext.OnModelCreating之前,EF Core将收集将应用的约定,传递给OnModelCreating的ModelBuilber将已经包含由约定发现的实体和属性 然而,约定并不只是代表“一开始就做一次,然后忘记它们”规则来确定模型,每当您使用Fluent API更改模型时,它们都会不断应用。如果手动添加实体,则此时将执行用于发现属性等的约定,并且模型始终保持最新 ConventionSet对象定义了一个“事件”列表,如“添加的实体类型”,并为每个事件定义了要执行的约定 其中一个事件是“ModelInitialized”,它在一开始就运行,通过DbSetFindingConvention最初标识实体。但是,此约定找到的每个实体类型都将触发“事件”EntyTypeAddedConventions,该EntyTypeAddedConventions随后将标识实体上的属性等。如果只是取消DbSetFindingConvention,则在手动向模型添加实体类型后,仍然会自动获取属性 为了抑制属性生成,还需要从EntyTypeAddedConventions中删除PropertyDiscoveryConvention 删除所有约定可能不是一个好主意,因为您需要手动执行所有操作,这是一项乏味的工作。但是,如果你很好地理解了你想使用的自动功能,以及哪种约定做了什么,你可以有选择地删除其中的一些 要取消约定,您可以交换–特定于数据库提供程序!!!–ConventionSetBuilder服务实现
public class CustomSqlServerConventionSetBuilder : SqlServerConventionSetBuilder {
//See also notes in CustomRuntimeConventionSetBuilder
public CustomSqlServerConventionSetBuilder([NotNullAttribute] ProviderConventionSetBuilderDependencies dependencies, [NotNullAttribute] RelationalConventionSetBuilderDependencies relationalDependencies, [NotNullAttribute] ISqlGenerationHelper sqlGenerationHelper)
: base(dependencies, relationalDependencies, sqlGenerationHelper) {
}
public override ConventionSet CreateConventionSet() {
ConventionSet cs = base.CreateConventionSet();
//Do not find entity types automatically
DbSetFindingConvention dbSetFindingConvention = cs.ModelInitializedConventions.OfType<DbSetFindingConvention>().FirstOrDefault();
if (dbSetFindingConvention != null) {
cs.ModelInitializedConventions.Remove(dbSetFindingConvention);
}
//Do not find properties automatically
PropertyDiscoveryConvention propertyDiscoveryConvention = cs.EntityTypeAddedConventions.OfType<PropertyDiscoveryConvention>().FirstOrDefault();
if (propertyDiscoveryConvention != null) {
cs.EntityTypeAddedConventions.Remove(propertyDiscoveryConvention);
}
propertyDiscoveryConvention = cs.EntityTypeBaseTypeChangedConventions.OfType<PropertyDiscoveryConvention>().FirstOrDefault();
if (propertyDiscoveryConvention != null) {
cs.EntityTypeBaseTypeChangedConventions.Remove(propertyDiscoveryConvention);
}
return cs;
}
}
公共类CustomSqlServerConventionSetBuilder:SqlServerConventionSetBuilder{
//另请参见CustomRuntimeConventionSetBuilder中的注释
公共自定义SQLServerConventionSetBuilder([NotNullAttribute]ProviderConventionSetBuilderDependencies依赖项,[NotNullAttribute]关系约定SetBuilderDependencies关系依赖项,[NotNullAttribute]ISqlGenerationHelper sqlGenerationHelper)
:base(依赖项、关系依赖项、sqlGenerationHelper){
}
公共覆盖约定集CreateConventionSet(){
ConventionSet cs=base.CreateConventionSet();
//不自动查找实体类型
DbSetFindingConvention DbSetFindingConvention=cs.ModelInitializedConventions.OfType().FirstOrDefault();
if(dbSetFindingConvention!=null){
cs.ModelInitializedConventions.Remove(dbSetFindingConvention);
}
//不自动查找属性
PropertyDiscoveryConvention PropertyDiscoveryConvention=cs.EntityTypeAddedConventions.OfType().FirstOrDefault();
if(propertyDiscoveryConvention!=null){
cs.EntityTypeAddedConventions.Remove(propertyDiscoveryConvention);
}
propertyDiscoveryConvention=cs.EntityTypeBaseTypeChangedConventions.OfType().FirstOrDefault();
if(propertyDiscoveryConvention!=null){
cs.EntityTypeBaseTypeChangedConventions.Remove(propertyDiscoveryConvention);
}
返回cs;
}
}
替换DbContext类中DI服务的默认实现(例如):
protectedoverride void onconfig(DbContextOptionsBuilder optionsBuilder){
optionsBuilder.ReplaceService();
}
或者,如果希望避免使此覆盖数据库提供程序特定,也可以将RuntimeConventionSetBuilder子类化,覆盖CreateConventionSet方法,并将其注册到服务IConventionSetBuilder。但这种接口在未来更有可能发生变化
公约的执行情况可在以下网址找到:
文档可在此处找到:
您应该检查特定约定实现了哪些“事件”,如果该约定应被抑制,则通常应从每个“事件”中删除该约定
这对EF Core 5.0有效,在以前的版本中可能有所不同。您还可以看看什么是“运行时错误”?@LeiYang该属性是/未配置的,我使用/不使用它,但不知道EF对它的看法不同。然而,这不是真正的问题-即使我没有收到错误,我仍然希望禁用此约定。@LeiYang我希望删除实际问题,即约定。如果可能的话,就是这样。我找不到办法,但EF Core中有很多东西还没有被记录下来,所以也许有办法,但我不知道。@LeiYang我知道,那又怎样?@LeiYang我想依靠官方的方法,而不是挖掘源代码。有些东西没有记录在官方网站上,而是在EF作者的各种博客上。我想知道什么是可能的。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
optionsBuilder.ReplaceService<Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure.IProviderConventionSetBuilder, TechnicalUtilities.CustomSqlServerConventionSetBuilder>();
}