【问题标题】:Entity Framework 6 not recognizing One-To-Many relationship when retrieving data实体框架 6 在检索数据时无法识别一对多关系
【发布时间】:2016-04-12 15:19:46
【问题描述】:

当我插入我的对象时,它们会识别出它们是一对多的,并且外键已正确放置在多边表中。 当我检索我的对象时,它们无法识别一侧表上的一对多,因此我无法访问多个侧对象的 ICollection。具体来说,尝试访问集合时会引发空引用异常/

在下面的解释中,事件是一方面,而干扰是多方面。一个事件与许多干扰相关联,但一个干扰只是一个事件的一部分。

免责声明:由于一些项目限制和一些构建在其他模块之上的模块,我们在 DAL 中使用实体框架,并且具有跨业务/数据的模型。这可能会影响问题。我知道这并不理想,但这就是我们所处的位置,我还没有看到任何明确说你不能像这样使用 EF 的东西。

我有一个这样定义的事件:

public class Incident
{
    public Incident()
    {

    }

    public Incident(List<Disturbance> sortedDisturbances)
    {
        StartTime = sortedDisturbances[0].StartTime;
        Disturbances = new List<Disturbance>(sortedDisturbances);
    }

    [Key]
    public int IncidentID { get; set; }

    public virtual ICollection<Disturbance> Disturbances { get; set; }

    [Column(TypeName="datetime2")]
    public DateTime? StartTime { get; set; }
}

我不得不添加一个无参数构造函数来处理由于实体框架尝试在某些区域使用无参数构造函数而导致的错误。

我有一个这样定义的干扰:

public class Disturbance : IComparable<Disturbance>
{
    [Key]
    public int DisturbanceID { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime StartTime { get; set; }

    [Column(TypeName = "datetime2")]
    public DateTime EndTime { get; set; }

    public int CompareTo(Disturbance other)
    {
        if (this.StartTime < other.StartTime)
            return 1;
        if (this.StartTime > other.StartTime)
            return -1;
        return 0;
    }
}

我没有读到任何说实现一个接口会破坏实体框架中的任何东西,所以我做到了。

这就是我添加事件的方式:

业务层:

private void MakeIncident(List<Disturbance> DisturbancesToAggregate)
{
    Incident incidentToInsert = new Incident(DisturbancesToAggregate);
    _iDAL.InsertIncident(incidentToInsert);
}

数据层:

public void InsertIncident(Incident incidentToInsert)
{
    using (var context = new InternalContext())
    {
        context.Incident.Add(incidentToInsert);                                                         
        context.SaveChanges();
    }
}

问题是当我访问我的事件时:

public IEnumerable<DomainModel.Disturbance> GetProcessedDisturbances()
{
    List<DomainModel.Disturbance> processedDisturbances = new List<DomainModel.Disturbance>();
    using(var context = new InternalContext())
    {
        foreach(var i in context.Incident)
        {
            foreach(var d in i.Disturbances)
            {
                processedDisturbances.Add(d);
            }
        }
    }
    return processedDisturbances;
}

i.Disturbances 集合导致空引用异常。我需要调用什么来强制上下文获取干扰吗?我是不是做错了什么?

我的想法(我不喜欢其中任何一个,也不想做任何一个): 1. 明确地将 IncidentID 放在 Disturbance 表上(甚至不确定这是否可行) 2. 通过添加 ICollection of Incidents 到 Disturbances 来强制查找表(它不是多对多关系,我认为这会阻止我从事件中清除所有 Disturbances) 3.在模型创建时明确定义关系。 (我不喜欢必须这样做的想法,而且我认为 EF 已经完成了一半,因为它插入正确。

【问题讨论】:

  • 请记住始终在无参数构造函数中初始化导航属性:Disturbances = new List&lt;Disturbance&gt;();
  • 检查延迟加载是否开启。或者试试var i in context.Incident.Include(e =&gt; e.Disturbances)
  • 您需要为 System.Data.Entity 添加一个 include 语句,用于 Include 的强类型版本。
  • @SmashCode 正确。这就是为什么我的第一条评论是检查延迟加载是否onvirtual 关键字只是其中之一。检查您的 DbContext Configuration.LazyLoadingEnabledConfiguration.ProxyCreationEnabled 属性是否为 true
  • @SmashCode 不用担心,伙计,很高兴有帮助。所有这些信息都可以在回答者发布的链接中找到,请随时接受他的回答。

标签: c# .net entity-framework entity-framework-6


【解决方案1】:

它的发生是因为 EF 中的延迟加载。我们需要急切地加载数据。要了解更多关于它们的信息,请参阅下面的链接。

https://msdn.microsoft.com/en-in/data/jj574232.aspx

【讨论】:

  • 我认为这是正确的方向,但是唯一可用的 .Include() 将字符串作为参数,而不是 lambda 表达式。目前正在寻找有关 Include 扩展的更多信息。
  • 尝试使用 using System.Data.Entity 命名空间,因为该方法仅在那里定义。
猜你喜欢
  • 2021-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多