EF6:如何避免循环引用?

Posted

技术标签:

【中文标题】EF6:如何避免循环引用?【英文标题】:EF6: How to avoid circular reference? 【发布时间】:2016-11-21 18:31:09 【问题描述】:

在使用 ASP.NET Web API 进行 JSON 序列化期间,有哪些可能避免使用 Entity Framework 6 进行循环引用?

我为 Entity Framework 6 生成了一个 edmx(实体数据模型)文件,首先是数据库。我尝试使用 ASP.NET Web API 构建 API。当我尝试在我的控制器中返回我的 JSON 对象时,由于循环引用,我得到了序列化的运行时异常。

确实,当我仔细检查我的数据库和我的实体时,我看到我的一个实体包含一个列表,另一个实体包含我以前的实体列表。假设我有一个包含作者的书籍实体,每个作者实体都包含一个书籍列表。这在相对数据库中很常见,但在 JSON 序列化中无法解决(或无法在 .NET 序列化程序中解决)。

我不想更改我的数据库,但我已准备好将错误的列表分解为我的实体或 edmx 文件。我能做什么?

我尝试过的:

我已经尝试过包含创建新模型或实体并使用映射工具的解决方案(http://www.codeproject.com/Articles/292970/Avoiding-Circular-Reference-for-Entity-in-JSON-Ser 或 Shawn Wildermuth 在 Pluralsight 上解释的解决方案)。

这个解决方案听起来更像是一种解决方法,而不是真正的解决方案。它应该存在于 edmx 文件或实体框架中,以告诉 JSON 序列化器什么会导致循环引用,什么可以且必须序列化,什么不能序列化,对吧?

【问题讨论】:

是的,您可以将此问题标记为重复。在这种情况下,请链接到重复的答案。除了我已经尝试过的,我什么也没找到。 它应该存在于 edmx 文件或实体框架中... -- 使用 EF 和 JSON 序列化的数据库交互是两个非常不同的概念。我不希望他们俩都不为对方负责。 【参考方案1】:

直接序列化领域模型在技术上是没有问题的。为避免循环引用,您不能使用延迟加载。您必须控制加载。这样做

    在模型的每个集合之前删除虚拟(在代码优先的方法中) 将延迟加载配置设置为 false(在数据库优先方法中)

【讨论】:

您是否尝试过忽略引用循环处理? ***.com/questions/19467673/…【参考方案2】:

不要尝试直接序列化您的域模型。创建一个视图模型,以您想要的确切格式返回数据。使用您的域模型来填充视图模型。更多信息在这里Why do we use ViewModels?

【讨论】:

我理解这个想法,但这不尊重不要重复自己的规则。 创建视图模型时,您定义了数据的公共视图。您的领域模型是您的团队和内部利益相关者描述您的业务功能的方式。您可能希望重构这些内部结构,同时保持公众视图完全相同。【参考方案3】:

您需要有一个 ViewModel 作为 UI 和后端数据结构之间的接口。 后端数据结构旨在轻松存储和从数据库中检索。因此,通过编写一些 ViewModel “适配器”,您并没有违反“不要重复自己”的规则。

希望对你有帮助。

【讨论】:

【参考方案4】:

我今天必须解决同样的问题。对我来说,最简单明了的方法是从实体模型上的一个实体中删除 Navigation 属性。 打开您的 model.edmx 并删除导致循环引用的不需要的 Navigation 属性。你的情况

书籍参考作者。所以书实体模型具有作者导航属性。

如果您不希望 Author 引用 Book,只需从 edmx 文件的 Author 数据模型中删除 Book 导航属性。所以,只有一种方式引用。

【讨论】:

削弱数据层以满足一些不相关的需求?这是一个糟糕的解决方案。

以上是关于EF6:如何避免循环引用?的主要内容,如果未能解决你的问题,请参考以下文章

如何避免在Block里用self造成循环引用

如何避免 activesupport 中的循环参数引用警告

json数据避免$ref 循环引用

忽略或避免 UDF 中的循环引用?

避免 grails 中的循环引用继承

避免在Excel中循环引用