我希望通道中的继承类共享相同的外键,将Gateway_GatewayId和Gateway_GatewayId1列合并到GatewayId列中。
可以吗?
我试过这个:
modelBuilder.Entity<ChannelModbus>().HasRequired(d => d.Gateway).WithMany()
.HasForeignKey(d => d.GatewayId).WillCascadeOnDelete(false)
但是得到这个错误:
外键组件“GatewayId”不是声明的属性 输入'ChannelModbus'。验证是否未明确排除它 来自模型,它是一个有效的原始属性。
我也尝试过使用MapKey:
modelBuilder.Entity<ChannelModbus>().HasRequired(d => d.Gateway).WithMany()
.Map(d => d.MapKey("GatewayId")).WillCascadeOnDelete(false);
并收到此错误:
在模型生成期间检测到一个或多个验证错误:
GatewayId:名称:类型中的每个属性名称必须是唯一的。已定义属性名称“GatewayId”。
GatewayId:名称:类型中的每个属性名称必须是唯一的。已定义属性名称“GatewayId”。
public abstract class Channel
{
public int ChannelId { get; private set; }
public int GatewayId { get; set; }
}
public abstract class Gateway
{
public int GatewayId { get; private set; }
}
public abstract class GatewayTcp : Gateway
{
public string Ip { get; set; }
public int Puerto { get; set; }
}
public class GatewayModbus : GatewayTcp { }
public class GatewayXmlRpc : GatewayTcp { }
public class ChannelModbus : Channel
{
public virtual GatewayModbus Gateway { get; set; }
}
public class ChannelXmlRpc : Channel
{
public virtual GatewayXmlRpc Gateway { get; set; }
}
public partial class MyDbContext : DbContext
{
public IDbSet<Channel> Channels { get; set; }
public IDbSet<Gateway> Gateways { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Gateway>().Property(d => d.GatewayId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Gateway>().HasKey(d => d.GatewayId);
modelBuilder.Entity<Channel>().Property(d => d.ChannelId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Channel>().HasKey(d => d.ChannelId);
modelBuilder.Entity<ChannelModbus>().HasRequired(d => d.Gateway).WithMany().WillCascadeOnDelete(false);
modelBuilder.Entity<ChannelXmlRpc>().HasRequired(d => d.Gateway).WithMany().WillCascadeOnDelete(false);
//modelBuilder.Entity<ChannelModbus>().HasRequired(d => d.Gateway).WithMany().HasForeignKey(d => d.GatewayId).WillCascadeOnDelete(false);
//modelBuilder.Entity<ChannelXmlRpc>().HasRequired(d => d.Gateway).WithMany().HasForeignKey(d => d.GatewayId).WillCascadeOnDelete(false);
}
}
答案 0 :(得分:2)
是的,这是可能的。只需将Gateway
属性从ChannelModbus
和ChannelXmlRpc
移至基类Channel
。
public abstract class Channel
{
public int ChannelId { get; private set; }
public int GatewayId { get; set; }
public virtual GatewayModbus Gateway { get; set; }
}
当您在每个派生类上定义属性时,由于您使用TPH继承,因此所有列都将映射到单个表,一列属于ChannelModbus
,一列属于ChannelXmlRpc
,即使他们指的是同一个实体。通过将其移动到基类,两个派生类将使用相同的列作为外键。