2012-10-10 50 views
12

嘗試這個問題,同樣是因爲我第一次嘗試了幾乎一致的:對實體框架循環引用

所以我超困惑和使用實體框架代碼優先

我有一個森林類。

我有一個Tree類。

每個森林可以有許多樹木

當我試圖序列我得到循環引用

public class Forest 
{ 

    public Guid ID { get; set; } 
    public virtual List<Tree> Trees { get; set; } 
} 
public class Tree 
{ 
    public Guid ID { get; set; } 
    public Guid? ForestId {get;set;} 

    [ForeignKey("ForestId")] 
    public virtual Forest Forest {get;set;} 
} 

每個林中有樹,但不是每一種樹是在森林裏。我做

@(Html.Raw(Json.Encode(Model))) 

在機型是森林

當多重的任何錯誤的鬥爭,如果我做一個ForestIdGuid代替Guid?我得到循環引用錯誤。

我也試過 保護覆蓋無效提前

+0

您使用DataContractSerializer嗎?如果是這樣,我沒有看到你的DataContracts,但你需要設置IsReference = true。 –

回答

16

最好的辦法

OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Forest>() 
    .HasMany(x => x.Tree) 
    .WithOptional() 
    .HasForeignKey(y => y.ForestId); 
} 

感謝會,你應該使用DTO的傳輸只想要客戶端的數據。 DTO應該只有簡單的屬性,所以它不會創建循環引用錯誤。目前,森林具有List<Trees> Trees並在樹的每個Tree具有ForestForest又有List<Trees>

或者

可以裝飾用ScriptIgnore你的屬性爲您不想 Json的性能。編碼爲序列化,然後不會被髮送回客戶端。

http://msdn.microsoft.com/en-us/library/system.web.script.serialization.scriptignoreattribute.aspx

如:

public class Forest 
{  
    public Guid ID { get; set; } 
    public virtual List<Tree> Trees { get; set; } 
} 
public class Tree 
{ 
    public Guid ID { get; set; } 
    public Guid? ForestId {get;set;} 

    [ForeignKey("ForestId")] 
    [ScriptIgnore] 
    public virtual Forest Forest {get;set;} 
} 

編輯:

隨着ScriptIgnore你也應該從ForestTrees刪除virtual而且是可行的。我測試過了。不過,我不會建議,因爲虛擬關鍵字是什麼懶惰加載。因此,正如我所說的,您需要根據這些模型創建DTO,並只將DTO發送到客戶端。

+0

即使有腳本忽略它給了我循環引用,所以我看着模型。樹的ID字段會繼續向下鑽取,就像森林的ID字段一樣。 我正在使用NewId()在數據庫中生成的GUID可能導致我的問題?我甚至在Forest中設置了Trees = null,但它仍然給出了循環引用。 – Jordan

+0

@Jordan:看我的編輯。 – TCM

+0

非常感謝。我昨天晚上意識到我可以把虛擬關閉。我意識到這不是理想的解決方案,但我只是爲這個項目建立原型,所以在這個例子中它很好。在未來的製作工作中,我確實會使用DTO! 非常感謝! – Jordan

相關問題