EFCore中如何给所有实体添加相同的列?想象一下,我想向我的所有实体添加一个IsDeleted列或一些审计列。我可以创建一个基类,我的所有实体都将从中继承,这将解决我的问题,但我无法指定创建列的顺序,所以我将在实体字段之前获取所有审计字段,我不想。我要他们在桌子的尽头。在实体框架的标准版本中,我们可以使用指定列顺序的注释来做到这一点。但是,目前EF核心中不存在这样的东西。我可以在OnModelCreating()方法上使用流畅的api来完成,问题是我只知道如何为我的每个实体单独执行它,这意味着我必须为我拥有的每个实体编写相同的代码。有什么办法可以为我的所有实体执行此操作吗?某种for循环遍历在dbcontext上的DbSets中注册的所有实体?您的问题标题是关于将相同的属性添加到多个实体。但是,您实际上知道如何实现这一点(使用基本类型),您实际的问题是如何确保这些属性在结果表的列中排在最后。虽然现在列顺序应该并不重要,但我将展示一个替代方案,您可以在其中做得比基类型更好,并将公共属性放在表的末尾。它使用影子属性:影子属性是未在.NET实体类中定义但在该实体类型的EFCore模型中定义的属性。大多数时候审计属性在应用程序中不需要太多可见性,所以我认为影子属性正是您所需要的。这是一个例子:我有两个类:publicclassPlanet{publicPlanet(){Moons=newHashSet();}publicintID{得到;放;}公共字符串名称{得到;放;}publicvirtualICollectionMoons}}publicclassMoon{publicintID{get;放;}publicintPlanetID{得到;放;}公共字符串名称{得到;放;}publicPlanetPlanet{get;放;如你所见:它们没有审计属性,它们是非常卑鄙和精简的POCO。(顺便说一下,为方便起见,我将IsDeleted与“审计属性”进行了整理,虽然它不是一个,但它可能需要另一种方法)。也许这就是这里的主要信息:类模型不会受到审计问题(单一责任)的影响,这都是EF的事。审计属性将作为影子属性添加。由于我们想为每个实体执行此操作,因此我们定义了一个基础IEntityTypeConfiguration:(错误的);builder.Property("InsertDateTime").IsRequired().HasDefaultValueSql("SYSDATETIME()").ValueGeneratedOnAdd();builder.Property("UpdateDateTime").IsRequired().HasDefaultValueSql("SYSDATETIME()").ValueGeneratedOnAdd();}}具体的配置是从这个基类派生的://遵循默认约定,但添加后有所不同:)builder.HasMany(p=>p.Moons).WithOne(m=>m.Planet).IsRequired().HasForeignKey(m=>m.PlanetID);base.Configure(建造者);}}publicclassMoonConfig:BaseEntityTypeConfiguration{publicoverridevoidConfigure(EntityTypeBuilderbuilder){builder.Property(p=>p.ID).ValueGeneratedOnAdd();base.Configure(建造者);这些应该添加到OnModelCreating的上下文模型中:modelBuilder.ApplyConfiguration(newMoonConfig());这将在末尾生成一个带有InsertDateTime、IsDeleted和UpdateDateTime列的数据库表(独立于base.Configure(builder)BTW),尽管base.Configure(builder)顺序(字母顺序)我想这很接近。为了使图片完整,下面是如何在SaveChanges覆盖中完全自动设置值:p=>p.Metadata.Name=="UpdateDateTime")&&e.State!=Microsoft.EntityFrameworkCore.EntityState.Added)){entry.Property("UpdateDateTime").CurrentValue=DateTime.Now;}返回base.SaveChanges();小细节:我确保在插入实体时,数据库默认设置两个字段(见上文:ValueGeneratedOnAdd(),所以添加的实体被排除在外),所以没有由于客户端时钟稍微关闭而造成的混淆差异。我认为更新总是会迟到。要设置IsDeleted,您可以将此方法添加到上下文中:publicvoidMarkForDelete(Tentity)whereT:class{varentry=this.Entry(entity);//TODO:检查entry.Stateif(entry.Properties.Any(p=>p.Metadata.Name=="IsDeleted")){entry.Property("IsDeleted").CurrentValue=true;}else{entry.State=Microsoft.EntityFrameworkCore.EntityState.Deleted;}}...或转向建议的机制之一,是将EntityState.Deleted转换为IsDeleted=true。您始终可以为模型生成初始迁移并手动重新排列迁移中的列顺序。这是一个未解决的问题,跟踪了对EFCore中显式列排序的支持:https://github.com/aspnet/EntityFrameworkCore/issues/10059另请参阅有关使用“影子属性”和“查询过滤器”进行软删除的问题和答案。EFCore:使用影子属性和查询过滤器进行软删除以上是C#学习教程:如何在EFCore中为所有实体添加相同的列?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
