简体   繁体   中英

Access parent entity from child in Entity Framework

I have a parent entity Device which contains a list of DeviceErrorLog setup like so

public class Device
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public long DeviceSerial { get; set; }

    public virtual ICollection<DeviceLogEntry> Errors { get; set; }
}

This works fine but I want to be able to access Device from within DeviceLogEntry so I added the following:

public class DeviceLogEntry
{        
    [Key]
    public int Id { get; set; }

    public virtual Device Device { get; set; }
}

Now my database structure for the DeviceLogEntry table has 3 columns associated with the Device : [Device_DeviceSerial],[Device_DeviceSerial1],[Device_DeviceSerial2]

Have I missed a link or bit of code that prevents this?

Update

I have updated the code to include the device as a foreign key which has removed one extra column but I still seem to have one too many [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; }
}

You re trying to model a one-to-many relationship. The child entity will need a foreign key in the database to the parent's ID but you are not following naming conventions so EF does not know they are modelling the same relationship and is adding independent columns for the 'DeviceSerial' property, the 'Errors' property and the 'Device' property. Try this:

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

References:

Code First Data Annotations

Making Do with Absent Foreign Keys

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM