2011-11-02 73 views
11

我有一個實體框架實體,我想序列化爲json對象。我環顧四周,發現json.net(http://james.newtonking.com/projects/json-net.aspx)應該能夠使用「開箱即用」的循環引用序列化對象。所以我嘗試使用json.net;序列化實體框架對象(循環引用錯誤)

string json = JsonConvert.SerializeObject(/* my ef entity */); 

但即時通訊仍然收到相同的錯誤。問題可能是我需要使用ReferenceLoopHandling.IgnoreContractResolver,但我不知道如何使用它們。任何幫助深表感謝!謝謝

+0

[序號實體框架對象轉換JSON]的可能重複(http://stackoverflow.com/questions/657939/serialize-entity-framework-objects-into- json) –

+2

@CraigStuntz不,因爲我不想將屬性maunally映射到一個新對象上。並問我如何使用JSON.NET完成 – Johan

+0

建議的解決方案將適用於JSON.NET。如果你真的寧願處理循環引用而不是賦值語句,那麼這取決於你。但JSON.NET並不意味着其他解決方案將無法正常工作。 –

回答

2

我的解決方案是簡單地刪除我的子實體的父引用。

所以在我的模型中,我選擇了關係,並將Parent引用改爲Internal,而不是Public。

可能不是一個理想的解決方案,但爲我工作。

14

爲了解決這個問題,我將我的實體轉換爲基於POCO的Code First。爲此,請在您的edmx窗口中右鍵單擊並選擇:

添加代碼生成項>代碼選項卡> EF POCO實體生成器。

請注意,如果您沒有看到它,您可能需要使用nuget安裝它。

但是,在運行時,EF會將代理類添加到這些對象用於跟蹤目的,但它們往往會搞亂序列化過程。爲了防止這種情況,我們可以簡單地設置ProxyCreationEnabled爲false如下:

return JsonConvert.SerializeObject(results, Formatting.Indented, 
    new JsonSerializerSettings { 
     ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
    }); 
+4

'ReferenceLoopHandling.Ignore' +1 - 拯救了我的一天! – nrodic

1

試試這個:

var context = new YourEntities(); 
context.Configuration.ProxyCreationEnabled = false; 

var results = context.YourEntity.Take(100).ToList(); 

然後,您可以安全地通過省略默認參考循環如下返回JSON.NET串行數據首先確保POCO或模型具有DataContract,DataMemeber和刪除虛擬鍵word..then ..

public string Get() 
    { 
     var list = _languageRepository.GetMany(l => l.LanguageTrans.FirstOrDefault().CultureCode == "en").ToList(); 

     string json = JsonConvert.SerializeObject(list, Formatting.Indented, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }); 

     return json; 
    } 
+0

這樣你可以保留相關實體... – Bryant

9

另一種解決方案將增加[JsonIgnore] attribut e導航屬性。

例如:

using System; 
using System.ComponentModel.DataAnnotations.Schema; 

[Serializable] 
public class Entity 
{ 
    public int EntityID { get; set; } 
    public string EntityName { get; set; } 

    [JsonIgnore] 
    public virtual Parent Parent { get; set; } 
    [JsonIgnore] 
    public virtual List<Child> Children { get; set; } 
} 
+0

這是正確的答案,實體之間應該互相引用。但是您需要忽略子項中的主實體屬性。 – Darren

+1

但是,如果我想從子元素的角度來看待關係呢? –

6

我用以下解決方案來克隆我的實體,沒有章法,其中在實體上和我的表循環引用所需的有關數據屬性得到了保留。我甚至有實體互相指責對方沒有任何問題。 serializaton所需的庫是Json.Net(Newtonsoft.Json dll)。

private static T CloneObject<T>(T obj) 
    { 
     if (obj == null) 
      return obj; 
     string ser = JsonConvert.SerializeObject(obj, Formatting.Indented, 
      new JsonSerializerSettings() { 
           NullValueHandling = NullValueHandling.Ignore, 
           MissingMemberHandling = MissingMemberHandling.Ignore, 
           ReferenceLoopHandling = ReferenceLoopHandling.Ignore}); 
     return (T) JsonConvert.DeserializeObject(ser, obj.GetType()); 
    } 

實例:

protected object CopyObj(Object obj) 
    { 
     return CloneObject(obj); 
    } 
    var cust1 = this.cts.Customers().Where(cc => cc.Id == 3).Include(cc => cc.Addresses).FirstOrDefault(); 
    var cust2 = CopyObj(cust1) as Customers; 
    //Cust2 now includes copies of the customer record and its addresses 
相關問題