2017-03-15 22 views
2

我已经阅读了很多此问题的解决方案,但都没有为我工作。检测到自检回路

我有事件和用户对象之间的循环关系:

public class Event : EntityData 
{ 
    [Required] 
    [ForeignKey("Creator")] 
    public string CreatorId { get; set; } 
    public User Creator { get; set; } 

    [InverseProperty("ParticipantIn")] 
    public virtual ICollection<User> Participants { get; set; } 

    [InverseProperty("ManagerIn")] 
    public virtual ICollection<User> Managers { get; set; } 
} 

正如你可以看到我有这个类用户三个参考:事件的创造者,管理人员的名单,和与会者名单。

用户类包含对事件的引用,以及:

public class User: EntityData 
{ 
    [InverseProperty("Participants")] 
    public virtual ICollection<Event> ParticipantIn { get; set; } 

    [InverseProperty("Managers")] 
    public virtual ICollection<Event> ManagerIn { get; set; } 
} 

现在,问题是,当我试图序列的事件,就像在我createEvent功能,它告诉我,有一个自我引用循环,这是因为当创建事件时,我将它添加到创作者的'ManagerIn'集合中。

这行导致事件 - >创建器> ManagerIn->事件 - >创作者 - > ..... LOOP

我想什么,我也有一个版本的代码的公共虚拟用户的创造者,为了使其加载懒洋洋地..

现在,我的解决方案是非常不优雅,事件返回到客户端之前,我执行:

event.Creator = null; 

event.Managers = null; 

为了避免自引用循环。

解决这类问题的正确方法是什么?

在此先感谢, Liran!

+0

你用什么来序列化它? – Evk

+1

如果您使用的是XML http://stackoverflow.com/questions/5004397/is-it-possible-to-perform-serialization-with-circular-references可能是相关的 – Chris

+1

http://stackoverflow.com/questions/ 26434738 /你怎么真的序列化循环引用对象与牛顿软件json可能是有趣的json – Chris

回答

0

我读过这是这样做的一种方法。

MyContextEntities.ContextOptions.ProxyCreationEnabled = false; 

否则,我会建议序列化到一个不同的对象,并避免序列化您的poco的。

0

由于您将集合指定为virtual,因此实体框架正在加载正在构建带有循环引用的对象的相关实体,而WebAPI JSON序列化程序并未特别适用。

可以使用

MyEntities.Configuration.LazyLoadingEnabled = false; 

禁用对特定的查询或查询延迟加载或者,如果你想,从财产申报取出virtual关键字。随着这些选项,然后你可以贪婪加载如果使用Include扩展方法,像这样需要相关集合:

MyEntities.Set<Users>() 
    .Include(u => u.ManagerIn) 
    .Include("ParticipantIn"); 

(上面展示了使用包括对贪婪加载这两个选项)

Load方法也可以用来显式加载相关的实体。包含vs.堆栈溢出Here加载

我也做了类似于你指定的相关实体集合为null以防止被包含在序列化中的内容。为此,我建议首先将您的POCO /实体映射到DTO(数据传输对象),以便您可以设置可重复的内容并避免在同一上下文中意外调用SaveChanges(),并无意中删除SQL中实体之间的关系。 Automapper是一个现有的解决方案,可以将其映射到DTO,或者您可以编写自己的Mapper实用程序类来给自己多一点控制权。

最后一个潜在选项(我知道)是调整HttpConfiguration.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandinging设置忽略所有/数组/对象的引用处理。

它确实取决于您的要求和其他代码。希望其中的一个将你引向正确的道路,祝你好运!

+0

嗨!感谢您的指定答案。但无论我做什么,我仍然得到这个错误。让我举一个例子。在我的创建事件函数中,我正在执行var inserted = context.Events.Add(event);它添加事件,然后我找到用var creator = await context.Users.FindAsync(new object [] {creatorId})创建事件的用户,我这样做是为了执行creator.ManagerIn.Add(创建);所以这个活动将在他的名单上。只要我加载创建者对象,插入的对象现在包含对参考事件等的创建者的循环引用。 –