从Entity Framework中的子级访问父实体

时间:2014-01-08 13:41:59

标签: c# entity-framework

我有一个父实体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; }
}

1 个答案:

答案 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;)
}

参考文献:

Code First Data Annotations

Making Do with Absent Foreign Keys