【问题标题】:Get foreign key value using Entity Framework code first首先使用实体​​框架代码获取外键值
【发布时间】:2013-09-01 21:10:09
【问题描述】:

我有两种模型,一种用于设备类型,另一种用于设备问题。这里的关系是一个(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 is inferring lazy-loading。您可以在 DbContext 中调整延迟加载,或者在查询主对象时使用 .Include() 方法(因此它也可以获取关联)。例如context.DeviceTypes.Include(x =&gt; x.DeviceIssues)

标签: c# database entity-framework ef-code-first


【解决方案1】:

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

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

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

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

但是,如果您发现这很常见,您可以随时在 DbContext 构造函数中调整延迟加载:

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

【讨论】:

  • 使用此方法会产生以下错误:Cannot resolve symbol 'Include' 是否需要程序集才能使用此方法?
  • 我在一个WCF项目中使用这个,在调用使用这个代码的具体操作合约时出现以下错误An error occurred while receiving the HTTP response to http://xx.xx.x.xx:8200/Services/WCFClient.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.]
  • @Oxymoron:启用跟踪,看看是否有任何有见地的东西出现。
  • 它有,序列化,循环引用,试图弄清楚如何改变序列化。找到stackoverflow.com/questions/6485533/…,但无法准确理解我需要做什么
  • 如果您将 POCO 发回,它们是否标记为 [DataContract] 实体?
猜你喜欢
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2016-09-25
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-05
相关资源
最近更新 更多