Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在基类中共享外键的实体框架 问题_C#_Entity Framework - Fatal编程技术网

C# 在基类中共享外键的实体框架 问题

C# 在基类中共享外键的实体框架 问题,c#,entity-framework,C#,Entity Framework,我希望从通道继承的类共享相同的外键,将Gateway\u GatewayId和Gateway\u GatewayId1列合并到GatewayId列中 可以吗? 我试过这个: modelBuilder.Entity<ChannelModbus>().HasRequired(d => d.Gateway).WithMany() .HasForeignKey(d => d.GatewayId).WillCascadeOnDelete(false) m

我希望从通道继承的类共享相同的外键,将Gateway\u GatewayId和Gateway\u GatewayId1列合并到GatewayId列中

可以吗?

我试过这个:

modelBuilder.Entity<ChannelModbus>().HasRequired(d => d.Gateway).WithMany()
            .HasForeignKey(d => d.GatewayId).WillCascadeOnDelete(false)
modelBuilder.Entity().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);
modelBuilder.Entity().HasRequired(d=>d.Gateway).WithMany()
.Map(d=>d.MapKey(“网关ID”)).WillCascadeOnDelete(false);
并获取以下错误:

在模型生成过程中检测到一个或多个验证错误:

GatewayId:Name:类型中的每个属性名称都必须是唯一的。已定义属性名称“GatewayId”

GatewayId:Name:类型中的每个属性名称都必须是唯一的。已定义属性名称“GatewayId”

代码
公共抽象类频道
{
public int ChannelId{get;private set;}
公共int网关ID{get;set;}
}
公共抽象类网关
{
public int GatewayId{get;private set;}
}
公共抽象类GatewayTcp:网关
{
公共字符串Ip{get;set;}
公共整数{get;set;}
}
公共类网关Modbus:GatewayTcp{}
公共类GatewayXmlRpc:GatewayTcp{}
公共类信道Modbus:信道
{
公共虚拟网关Modbus网关{get;set;}
}
公共类ChannelXmlRpc:Channel
{
公共虚拟网关XMLRPC网关{get;set;}
}
公共部分类MyDbContext:DbContext
{
公共IDbSet通道{get;set;}
公共IDbSet网关{get;set;}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder){
modelBuilder.Conventions.Remove();
modelBuilder.Entity().Property(d=>d.GatewayId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity().HasKey(d=>d.GatewayId);
modelBuilder.Entity().Property(d=>d.ChannelId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity().HasKey(d=>d.ChannelId);
modelBuilder.Entity().HasRequired(d=>d.Gateway).WithMany().WillCascadeOnDelete(false);
modelBuilder.Entity().HasRequired(d=>d.Gateway).WithMany().WillCascadeOnDelete(false);
//modelBuilder.Entity().HasRequired(d=>d.Gateway).WithMany().HasForeignKey(d=>d.GatewayId).WillCascadeOnDelete(false);
//modelBuilder.Entity().HasRequired(d=>d.Gateway).WithMany().HasForeignKey(d=>d.GatewayId).WillCascadeOnDelete(false);
}
}

是的,这是可能的。只需将
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
,即使它们引用相同的实体。通过将其移动到基类,两个派生类将使用相同的列作为外键。

但是网关属性在每个通道中具有不同的类型。ChannelModbus网关属性类型为GatewayModBus,ChannelXmlRpc网关属性类型为GatewayXmlRpc。两者都从网关继承,但都有自己的属性。我知道一个解决方案是使用您的解决方案,并在每个通道中添加一个具有getter强制转换的属性到正确的类型。。。但我很好奇是否可以用其他方式完成。我认为这是不可能的,当使用TPH时,派生类上的每个属性都将映射到单独的列中,您可以在应用程序上进行验证,只允许将
GatewayModbus
实例设置为
ChannelModbus::Gateway
,覆盖
SaveChanges
并检查ChangeTracker
public abstract class Channel
{
    public int ChannelId { get; private set; }
    public int GatewayId { get; set; }
    public virtual GatewayModbus Gateway { get; set; }
}