我首先使用Entity Framework代码进行数据访问,并且我有一个具有Employees集合的Company类。 Employee类还有一个Company属性。
我希望能够序列化公司并在序列化中包含员工列表。
这是公司:
public class Company
{
public long Id { get; set; }
public string Name { get; set; }
public DateTime? Established { get; set; }
public virtual IList<Employee> Employees { get; set; }
public DateTime? DateCreated { get; set; }
public DateTime? DateUpdated { get; set; }
}
这是员工
public class Employee
{
public long Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public virtual Company Company { get; set; }
public DateTime? DateCreated { get; set; }
public DateTime? DateUpdated { get; set; }
}
当我尝试序列化Company对象时,我得到序列化异常“检测到类型的自引用循环”。
感谢。
答案 0 :(得分:14)
我认为他们已经在最新版本中解决了这个问题。
查看“序列化和反序列化JSON - &gt;序列化和保留对象引用”部分下的help docs。
初始化JSON.Net Serializer时设置此设置:
PreserveReferencesHandling = PreserveReferencesHandling.Objects;
一个例子是:
var serializerSettings = new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects };
string json = JsonConvert.SerializeObject(people, Formatting.Indented, serializerSettings);
我确认这适用于我的代码第一个解决方案,以及导航属性中的循环引用。如果你看看生成的JSON,它应该在任何地方都有“$ id”和“$ ref”属性。
答案 1 :(得分:6)
更新的答案
你可以:
答案 2 :(得分:5)
如果这有助于任何人,我想我会记录在使用Entity Framework 4.3.1和JSON.Net 4.5.3时我们如何为我们的目的解决同样的错误。
我们正在使用Database First DbContext方法。根据我们的需求,我们可以使用[JsonIgnore]
属性解决此问题。诀窍在于,当您从数据库刷新时会覆盖对自动生成的实体类的更改,使用Database First,您可以使用this StackOverflow post中给出的“元数据伙伴类”方法添加属性。
以下是代码摘录。我们有一个“查询”对象(class Query
)与“公司”和“用户”对象有关系。在新的类文件中,我们使用[MetadataType]
属性声明部分类,然后在我们指定的QueryMetadata
类中,我们注释要忽略的成员 - 即public virtual
成员EF4.x添加表达关系(又名导航属性)。
Query
实体还有外键字段(在我们的例子中名为FK_User
和FK_Company
)。这些字段不需要[JsonIgnore]
属性 - 它们可以使用其外键值序列化。
[MetadataType(typeof(QueryMetadata))]
public partial class Query
{
}
public class QueryMetadata
{
[JsonIgnore]
public virtual Company company { get; set; }
[JsonIgnore]
public virtual User user { get; set; }
}
但是,如果我们真的不得不序列化相关的公司或用户对象,我们就会碰壁砖墙! John Bubriski here建议的方法对我们不起作用,因为我们希望依赖实体框架更改跟踪。
答案 3 :(得分:5)
如果您使用WebApi收到此错误,可以将以下内容放在WebApiConfig.cs中,以便json.net忽略循环引用
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
答案 4 :(得分:1)
如果你正在使用WebAPI EntityFrameworkCore 2.0,这个解决方案不起作用,你需要在Startup.cs-&gt; ConfigureServices上设置它:
.AddJsonOptions(options => {
var settings = options.SerializerSettings;
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});