Get foreign key value using Entity Framework code first

c# database ef-code-first entity-framework


I have two models, one for device types, and another for device issues. The relationship here is one(DeviceType) to many(DeviceIssues). Here are the models:

public class DeviceType : ModelBase
    public string Manufacture { get; set; }
    public DeviceTypes Type { get; set; }
    public string Model { get; set; }

    public virtual ICollection<DeviceIssue> Issues { get; set; }

public class DeviceIssue : ModelBase
    public string Description { get; set; }
    public decimal RepairCost { get; set; }

    public int DeviceTypeId { get; set; }
    public virtual DeviceType DeviceType { get; set; }

public abstract class ModelBase
    public int Id { get; set; }
    public Guid Guid { get; set; }
    public DateTime FirstCreated { get; set; }
    public string LastUpdateUser { get; set; }
    public DateTime LastUpdateDt { get; set; }
    public bool IsDeleted { get; set; }

I have to database populated with several entities, using the seed method, and their foreign keys are intact. However when I get the list of device types, I do not also get the associated list of issues for each device. I am using AutoMapper, however, while debugging the variable which stores the query result doesn't show the data either. Here is the code I am using to make the calls:

var result = new List<DeviceTypeDataContract>();
using (var context = new DSPEntities())
    var devices = context.DeviceTypes;
    foreach (var device in devices)
        //var issues = context.DeviceIssues.Where(i => i.DeviceTypeId == device.Id).ToList();

        var devi = Mapper.Map<DeviceType, DeviceTypeDataContract>(device);

now as stated, while debugging, inspecting the variable device in foreach(var device in devices), shows the following similar result each time:

device.Issues = null,
device.manufacture = "Apple",
device.Model = "iPhone 3S",
device.Type = DeviceTypes.SmartPhone,

If you notice in my code there is a commented out line of code. This is commented because it throws the following inner exception:

{"There is already an open DataReader associated with this Command which must be closed first."}

I don't know if this has to do with my specific issue or not though.

My question is, how do i retrieve the data from those relationships?

Note: The relationships do exist, because outside the foreach statement, calling the following:

var issues = context.DeviceIssues.Where(i => i.DeviceTypeId == 1).ToList();

gives the following result:

issues[6].Description = "Water Damage",
issues[6].RepairCost = 0.00,
issues[6].DeviceTypeId = 1,
issues[6].DeviceType = [+]{Data.Model.DeviceType},
// The last property holds values similar to above.
// Except now the list of issues is populated.

Note the above comment: "except now the list of issues is populated."

9/17/2013 3:53:58 PM

Accepted Answer

When you decorate associations with virtual you are inferring them to be lazy loaded. This means that the primary collection (in this case DeviceTypes) is loaded but, until you try to access it, Issues won't be populated with any information.

There are multiple ways to get around this, but simplest (and most efficient) is load the associations when you need them using the Include method. e.g.

var devices = context.DeviceTypes.Include(x => x.Issues);

This will load the original collection (DeviceTypes) as well as populate the Issues for each type. This is usually the best way as you're only grabbing information you need to get your unit of work completed when it's needed.

If you find this to be common, however, you can always adjust lazy loading in your DbContext constructor:

public DSPEntities()
    this.Configuration.LazyLoadingEnabled = false;
5/23/2017 12:14:08 PM

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow