【问题标题】:Circular references and stack overflow exceptions循环引用和堆栈溢出异常
【发布时间】:2014-08-22 08:40:16
【问题描述】:

我在 KundeInfo 和 HovedKategori 之间有这样多对多的关联,我已将其映射到我的 MS SQL 数据库中,如下所示:

我已经实现了 KundeInfo.HovedKategoris 方法:

public IEnumerable<KundeInfo> KundeInfos
{
    get
    {
        using (var dc = new DataClassesBSMAKSDataContext())
        {
            dc.DeferredLoadingEnabled = false;
            var kundeInfoHovedKategoris = dc.KundeInfoHovedKategoris.Where(x => x.HovedKategori_Id == Id);
            var kundeInfos = dc.KundeInfos.Where(x => kundeInfoHovedKategoris.Any(y => y.KundeInfo_Id == x.Id));

            return kundeInfos.ToList();
        }
    }
}

... 和 HovedKategori.KundeInfos:

public IEnumerable<HovedKategori> HovedKategoris
{
    get
    {
        using (var dc = new DataClassesBSMAKSDataContext())
        {
            var kundeInfoHovedKategoris = dc.KundeInfoHovedKategoris.Where(x => x.KundeInfo_Id == Id);
            var hovedKategoris = dc.HovedKategoris.Where(x => kundeInfoHovedKategoris.Any(y => y.HovedKategori_Id == x.Id));

            return hovedKategoris.ToList();
        }
    }
}

这会从特定的 HovedKategori 和相反的方向检索相关的 KundeInfos。然而,问题在于序列化。当我调用 ToList() 或将这些对象序列化为 JSON 时,linq 将尝试首先跟踪 HovedKategori.KundeInfos 返回的所有引用,如果是我首先调用的那个方法,然后它会针对每个返回的对象,尝试跟踪 KundeInfo.HovedKategoris 等返回的所有引用,直到它会抛出堆栈溢出异常。

如果我能以某种方式阻止 linq 使用 [Ignore] 属性或其他东西来跟踪某些属性,它会起作用,但我找不到类似的东西。

在这种情况下我该怎么办?

【问题讨论】:

  • 当您致电ToList() 时,您确定收到了 SO? JSON序列化你用什么?
  • 我的理解是,当调用 ToList 时,Linq 会遍历对象的分支及其属性,因为它是从 linq 结果集中制成的列表。当我调用 ToList 或使用 Newtonsoft.Json 序列化对象时,堆栈溢出异常会正确抛出。我什至告诉 Newtonsoft.Json 不要遵循引用,但这没关系,因为似乎是 linq 使循环引用发生。

标签: sql-server asp.net-mvc linq


【解决方案1】:

这部分是设计问题。您真正应该问自己的是,您是否需要所有可能方向的导航属性。例如,如果您只是添加一个类别 ID 而不是导航属性,您仍然可以查询您的上下文(通过使用该 ID),但您真的需要始终获取所有类别的所有基础数​​据吗?

此外,如果您将属性设为虚拟,则您会延迟加载,并且只有在 .Include 或明确引用时才会获取信息。

【讨论】:

    【解决方案2】:

    好的 - 所以我解决了这个问题,只是把它变成了各个类的方法,首先应该是它,因为它从数据库中检索了这些实体。所以是的,部分设计问题。

    Virtual 不起作用,我考虑过使用投影和抽象类,但它是继承和类转换的大海捞针,甚至不值得考虑。

    public IEnumerable<KundeInfo> KundeInfos()
    {
    
        using (var dc = new DataClassesBSMAKSDataContext())
        {
            var kundeInfoHovedKategoris = dc.KundeInfoHovedKategoris.Where(x => x.HovedKategori_Id == Id);
            var kundeInfos = dc.KundeInfos.Where(x => kundeInfoHovedKategoris.Any(y => y.KundeInfo_Id == x.Id));
    
            return kundeInfos.ToList();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-28
      • 2010-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多