2017-03-15 21 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(創建);所以這個活動將在他的名單上。只要我加載創建者對象,插入的對象現在包含對參考事件等的創建者的循環引用。 –