我有一个父实体Device
,其中包含DeviceErrorLog
设置列表,如此
public class Device
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long DeviceSerial { get; set; }
public virtual ICollection<DeviceLogEntry> Errors { get; set; }
}
这样可行,但我希望能够从Device
内访问DeviceLogEntry
,所以我添加了以下内容:
public class DeviceLogEntry
{
[Key]
public int Id { get; set; }
public virtual Device Device { get; set; }
}
现在,我DeviceLogEntry
表的数据库结构有3列与Device
相关联:[Device_DeviceSerial],[Device_DeviceSerial1],[Device_DeviceSerial2]
我是否错过了阻止此操作的链接或代码?
更新
我更新了代码,将设备包含为外键,删除了一个额外的列,但我似乎还有一个太多[Device_DeviceSerial],[Device_DeviceSerial1]
public class DeviceLogEntry
{
[Key, Column(Order = 0)]
public int Id { get; set; }
[Key, Column(Order = 1)]
[ForeignKey("Device")]
public long DeviceSerial { get; set; }
}
答案 0 :(得分:2)
你试图模拟一对多的关系。子实体将需要数据库中的外键到父ID,但您不遵循命名约定,因此EF不知道他们正在建模相同的关系并且正在为'DeviceSerial'属性添加独立列,'Errors'属性和'设备'属性。试试这个:
public class Device
{
//You need the Key annotation because the name does not follow the
//convention for a Key
//if you'd called it "DeviceID" or "ID" then you wouldn't need it
[Key]
//EF defaults int keys to Identity
//assuming longs are the same you need this annotation to stop that
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long DeviceSerial { get; set; }
//This is a navigation property.
//The virtual keyword lets EF override the method in a proxy class
//so that it can support lazy loading.
//Convention would name it "DeviceLogEntries"
public virtual ICollection<DeviceLogEntry> Errors { get; set; }
}
public class DeviceLogEntry
{
//You don't need the Key annotation
public int Id { get; set; }
//You don't have to include the foreign key AND the navigation property
//in the entity but life is probably easier if you do...
public long DeviceSerial { get; set; }
//...so I would add the navigation property to your entity
//Foreign key doesn't follow convention (it's not "DeviceID")
//so you need to tell it what it is
[ForeignKey("DeviceSerial")]
//And again if the navigation property in the parent had been named
//"DeviceLogEntries" then you wouldn't need to tell EF that the
//inverse navigation property is actually called "Errors"
[InverseProperty("Errors")]
public virtual Device Device {get;set;)
}
参考文献: