在这里我有一个有点奇怪的场景,我有一个实体和一个多对多表。下表是这样的:
AssetHeader.cs
[Table("AssetHeader", Schema = "assets")]
public class AssetHeader
{
public Guid Id { get; set; }
public virtual ICollection<AssetHeaderEquipment> AssetHeaders { get; set; }
public virtual ICollection<AssetHeaderEquipment> AssetEquipment { get; set; }
}
AssetHeaderEquipment.cs(多对多)
[Table("AssetHeaderEquipment", Schema = "assets")]
public class AssetHeaderEquipment
{
[Key, Column(Order = 0)]
public Guid AssetHeaderId { get; set; }
[Key, Column(Order = 1)]
public Guid AssetEquipmentId { get; set; }
public virtual AssetHeader AssetHeader { get; set; }
public virtual AssetHeader AssetEquipment { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
[MaxLength(255)]
public string Comment { get; set; }
}
当我尝试通过代码优先迁移创建数据库时,在SQL中得到以下信息:
如何首先获得代码以生成正确的db结构,我很高兴在dbcontext中使用属性或流畅的语言。
答案 0 :(得分:0)
您可以在业务模型上使用IEntityTypeConfiguration
界面并配置外键。
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
public class AssetHeaderEquipment : IEntityTypeConfiguration<AssetHeaderEquipment>
{
public Guid AssetHeaderId { get; set; }
public virtual AssetHeader AssetHeader { get; set; }
public Guid AssetEquipmentId { get; set; }
public virtual AssetHeader AssetEquipment { get; set; }
//other properties
public void Configure(EntityTypeBuilder<AssetHeaderEquipment> builder)
{
builder.HasKey(x => new { x.AssetHeaderId, x.AssetEquipmentId });
builder.HasOne(x => x.AssetHeader).WithMany(x => x.AssetHeaders).HasForeignKey(x => x.AssetHeaderId);
builder.HasOne(x => x.AssetEquipment).WithMany(x => x.AssetEquipment).HasForeignKey(x => x.AssetEquipmentId);
}
}
然后在OnModelCreating
方法内添加以下行:
builder.ApplyConfiguration(new AssetHeaderEquipment());
答案 1 :(得分:0)
这是EF无法自动配对关系导航属性的情况之一。
通常,它可以使用InverseProperty
属性或Has
/ With
流利的API进行解析。但是,由于这种类型的关系始终会带来“多个级联路径”问题,这需要关闭至少一种关系的级联删除,并且只能使用fluent API才能完成,因此除了使用fluent API(对于关系,恕我直言更好。)
最低要求是配置要为其关闭级联删除的关系。一旦这样做,EF通常会做剩下的事情。
例如:
modelBuilder.Entity<AssetHeader>()
.HasMany(e => e.AssetEquipment)
.WithRequired(e => e.AssetEquipment)
.WillCascadeOnDelete(false);
结果:
CreateTable(
"assets.AssetHeaderEquipment",
c => new
{
AssetHeaderId = c.Guid(nullable: false),
AssetEquipmentId = c.Guid(nullable: false),
StartDate = c.DateTime(nullable: false),
EndDate = c.DateTime(),
Comment = c.String(maxLength: 255),
})
.PrimaryKey(t => new { t.AssetHeaderId, t.AssetEquipmentId })
.ForeignKey("assets.AssetHeader", t => t.AssetEquipmentId)
.ForeignKey("assets.AssetHeader", t => t.AssetHeaderId, cascadeDelete: true)
.Index(t => t.AssetHeaderId)
.Index(t => t.AssetEquipmentId);
CreateTable(
"assets.AssetHeader",
c => new
{
Id = c.Guid(nullable: false),
})
.PrimaryKey(t => t.Id);