C# 实体框架核心中父表上相同主键的多个1到0..1关系
假设我有以下对象C# 实体框架核心中父表上相同主键的多个1到0..1关系,c#,entity-framework-core,C#,Entity Framework Core,假设我有以下对象 武器 剑 来复枪 鞠躬 我想要以下结构 武器只能是其中的一种,但必须至少是一种 所有武器必须存放在同一地点 所有武器类型都必须存储在各自相应的表中,如剑、步枪、弓。(不重复数据) 这就是我所做的 我创建了一个名为IWeapon的界面,看起来像这样 public interface IWeapon { public int Id { get; set; } [Key, ForeignKey("Weapon")] public
- 武器
- 剑
- 来复枪
- 鞠躬
- 武器只能是其中的一种,但必须至少是一种
- 所有武器必须存放在同一地点
- 所有武器类型都必须存储在各自相应的表中,如剑、步枪、弓。(不重复数据)
我创建了一个名为
IWeapon
的界面,看起来像这样
public interface IWeapon
{
public int Id { get; set; }
[Key, ForeignKey("Weapon")]
public int WeaponId { get; set; }
public Weapon Weapon{ get; set; }
}
这是我的其他课程
public class Weapon
{
public int Id { get; set; }
public decimal Damage { get; set; }
public IWeapon ActualWeapon { get; set; }
}
public class Sword : IWeapon
{
public int Id { get; set; }
[Key, ForeignKey("Weapon")]
public int WeaponId { get; set; }
public Weapon Weapon{ get; set; }
//other properties and methods
}
//same for Rifle and Bow
在定义了我的结构之后,我试图让它在实体框架核心中工作。我在dbcontext中执行了以下操作,以建立1对1的关系
public DbSet<Weapon> Weapons { get; set; }
public DbSet<Sword> Swords { get; set; }
public DbSet<Rifle> Rifles { get; set; }
public DbSet<Bow> Bows { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Weapon>()
.HasOne(w => (Sword)w.ActualWeapon)
.WithOne()
.HasForeignKey<Sword>(WeaponT => WeaponT.WeaponId);
modelBuilder.Entity<Weapon>()
.HasOne(w => (Rifle)w.ActualWeapon)
.WithOne()
.HasForeignKey<Rifle>(WeaponT => WeaponT.WeaponId);
modelBuilder.Entity<Weapon>()
.HasOne(w => (Bow)w.ActualWeapon)
.WithOne()
.HasForeignKey<Bow>(WeaponT => WeaponT.WeaponId);
}
公共数据库集{get;set;}
公共DbSet剑{get;set;}
公共DbSet步枪{get;set;}
公共DbSet Bows{get;set;}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasOne(w=>(剑)w.实际武器)
.WithOne()
.HasForeignKey(WeaponT=>WeaponT.weapontid);
modelBuilder.Entity()
.HasOne(w=>(步枪)w.实际武器)
.WithOne()
.HasForeignKey(WeaponT=>WeaponT.weapontid);
modelBuilder.Entity()
.HasOne(w=>(船首)w.实际武器)
.WithOne()
.HasForeignKey(WeaponT=>WeaponT.weapontid);
}
我面临的问题是,只有最后建立的关系才有效。因此,在这种情况下,弓将起作用,假设它是,因为所有的关系都将指向同一列,那么它不知道要使用哪一个,并以我使用modelbuilder所做的铸造为基础
是否有一种方法可以设置多个1到0..1关系到同一列,同时仍保持此结构的大部分
运行scaffoldbcontext命令
DbContext.cs
拿武器
你的桌子看起来很奇怪。为什么不是只有一个表“武器”,而这个表有一列叫做“武器类型”(弓、剑等)?如果想要拥有不同类型的剑,请创建另一个带有“ID”、“武器ID”、“名称”(龙剑、蛇剑……)和“伤害”的新表“武器类型”。目前EF核心不支持(无法映射)此类模型。您必须重新审视您的设计,或者用抽象类替换接口,(1)删除单独的表要求,并使用现有的TPH映射,或者(2)等待EF Core 5.0和TPT映射。遗憾的是,该设计非常锁定,因为它与其他系统互连。这是我在不泄露IP的情况下可以解释的最简单的方法,但保留了完整的结构以给出一个可解决的问题。每种武器类型都由我所在的公司管理situation@IvanStoev您知道TPT映射何时完成吗。我读了TPT,也认为它可以解决我的问题。核心5.0是。TPT已在中可用。TWeapon表名应为TWeaponType。TWeaponType表名应为TWeapon。更合适。二十岁(剑、弓、步枪)。TWeapon(龙剑,蛇剑…)这是一个非常适合书本类型的解决方案,几乎适用于任何其他场景。。很遗憾,我不能走这条路。我会给你竖起大拇指的
public virtual DbSet<TWeapon> TWeapon { get; set; }
public virtual DbSet<TWeaponType> TWeaponType { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<TWeapon>(entity =>
{
entity.ToTable("T_Weapon");
entity.Property(e => e.Id).HasColumnName("ID");
entity.Property(e => e.Name).HasMaxLength(100);
});
modelBuilder.Entity<TWeaponType>(entity =>
{
entity.ToTable("T_WeaponType");
entity.Property(e => e.Id).HasColumnName("ID");
entity.Property(e => e.Damage).HasColumnType("decimal(18, 2)");
entity.Property(e => e.Name).HasMaxLength(100);
entity.Property(e => e.WeaponId).HasColumnName("WeaponID");
entity.HasOne(d => d.Weapon)
.WithMany(p => p.TWeaponType)
.HasForeignKey(d => d.WeaponId)
.HasConstraintName("FK_T_WeaponType_T_Weapon");
});
OnModelCreatingPartial(modelBuilder);
}
public partial class TWeapon
{
public TWeapon()
{
TWeaponType = new HashSet<TWeaponType>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<TWeaponType> TWeaponType { get; set; }
}
public partial class TWeaponType
{
public int Id { get; set; }
public int? WeaponId { get; set; }
public string Name { get; set; }
public decimal? Damage { get; set; }
public virtual TWeapon Weapon { get; set; }
}
var weapons = db.TWeapon.Include(x => x.TWeaponType).ToList();