首先使用实体框架代码获取外键值

本文关键字:代码 获取 键值 框架 实体 | 更新日期: 2023-09-27 18:29:25

我有两个型号,一个用于设备类型,另一个用于解决设备问题。这里的关系是一个(DeviceType)对多个(DeviceIssues)。以下是型号:

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

我必须使用种子方法用几个实体填充数据库,并且它们的外键完好无损。但是,当我获得设备类型列表时,我不会同时获得每个设备的相关问题列表。然而,在调试存储查询结果的变量时,我使用的是AutoMapper,它也不显示数据。这是我用来打电话的代码:

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);
        result.Add(devi);
    }
}

如前所述,在调试时,检查foreach(var device in devices)中的变量device,每次都会显示以下类似的结果:

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

如果你注意到我的代码中有一行注释掉的代码。之所以对此进行评论,是因为它抛出了以下内部异常:

{"已经有一个打开的DataReader与此命令关联,必须首先关闭。"}

我不知道这是否与我的具体问题有关。

我的问题是,如何从这些关系中检索数据

注意:关系确实存在,因为在foreach语句之外,调用以下内容:

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

给出以下结果:

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.

注意上面的注释:"除了现在问题列表已经填充。"

首先使用实体框架代码获取外键值

当您用virtual装饰关联时,您推断它们是惰性加载的。这意味着主集合(在本例中为DeviceTypes)已加载,但在尝试访问它之前,Issues不会填充任何信息。

有多种方法可以解决这个问题,但最简单(也是最有效)的方法是在需要时使用Include方法加载关联。例如

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

这将加载原始集合(DeviceTypes),并为每个类型填充Issues。这通常是最好的方法,因为你只是在需要的时候获取完成你的工作单元所需的信息。

然而,如果你发现这很常见,你可以随时调整DbContext构造函数中的延迟加载:

public DSPEntities()
{
    this.Configuration.LazyLoadingEnabled = false;
}