【问题标题】:Circular references not allowed - Json serialization不允许循环引用 - Json 序列化
【发布时间】:2011-08-13 12:27:17
【问题描述】:

我正在使用实体框架代码首先 4.1 和 MVC3 开发应用程序。以下是我拥有的三个实体,基本上,State => City => Locality。

public class State {
    public virtual List<City> Cities { get; set; }
}

public class City {
    public virtual List<Locality> Localities { get; set; }
    public virtual State State { get; set; }
}

public class Locality {
    public virtual City City { get; set; }
}

可以看出我对所有三个实体都使用了双向关系。 Json 不允许这样做,所以我有些沮丧。基本上,我需要朝任一方向导航。例如,给定一个城市,我希望能够轻松找到它所属的州。

我扫描了网络并找到了一些解决方法,但没有一个适合我的方案。第一个是使关系单向(谁会这样做!),我不希望那样。另一种是只引入我需要的属性的 ViewModel,但是如果我需要定期使用 Entity 的所有字段,那将意味着重复代码。我的控制器也会被这些属性淹没。所以我也不喜欢这样。

我以为这只是基本的东西,但现在我正在努力寻找可行的解决方案。如果有人有更好的选择(也许在 MVC3 中),请帮助我。

【问题讨论】:

    标签: json asp.net-mvc-3 entity-framework-4.1 ef-code-first


    【解决方案1】:

    您可以尝试直接使用 JavaScriptSerializer 并注册自己的 converter 来控制序列化过程。

    【讨论】:

    • 我觉得JavascriptSerializer似乎是一个更好的方法,虽然我还没有实现。但是,有一个名为 [ScriptIgnore] 的属性可以防止 json 导航定义了该属性的关系。我没有对它进行广泛的测试,但目前它似乎有效。我可以在我的 .net 代码中双向导航,即我有一个真正的双向关系。
    【解决方案2】:

    我不是 ASP 专家,但我认为解决方案可能与我在 Java、Groovy 或 python 或任何其他语言中所做的类似。

    我可以提出的最佳解决方案是使 City.Localities 成为一种“瞬态”(用 Java 术语)字段 - 即不要序列化它,而是在加载时更新它(当你构建结构时)。这可以封装在 Locality 类的 City 的 setter 中。 所以在 Locality.setCity 中,你应该在 set 方法中调用 (city->localities.append(this) (无论你用什么语言编写它)。这样它将成为 City->Localities 的“运行时缓存”,这将是在加载期间构建一次。

    【讨论】:

    • 我以前研究过java,但我不完全理解你的解决方案。在一个简单的场景中,如果我只加载一个城市会发生什么。在这种情况下,永远不会调用 Locality.setCity() ,我将不得不在我正在加载的城市中寻找地点。如果我无法理解,请原谅我。
    【解决方案3】:

    问题似乎是 DataContractJsonSerializer 对实体类型的支持的原生问题。简而言之,与其他实体类型有关系(即双向)的实体不能通过 Json 进行序列化。在您的示例中:连接到 Cities 表的 State 表无法很好地转换为 Json 序列化,因为一个州可能有许多城市,并且一个城市与一个州相关联。

    一种快速的解决方案是匿名对象投影。 像这样的例子:

    public JsonResult Orders()
        var results = from Ord in databaseContext.Orders
              select new
              {
                  OrderID = Ord.ID,
                  OrderTitle = Ord.Name,
                  OrderDate = Ord.OrderDate
              }
    
        return Json(results);
    }
    

    供参考,请参阅:Serializing Entity Framework Objects into JSON Using ASP.Net MVC

    【讨论】:

    • Ofer,我已经在我的问题中提到我不想用我想使用的属性污染我的控制器。这似乎是最简单的解决方案,但不知何故我不太可能使用它。非常感谢您的建议。
    • [ScriptIgnore] 会以某种方式污染您的实体。但是我从这个问答中学到了一些新东西,JavaScriptSerializer 技术!感谢 Nirvan 和 @marcind。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多