![](/img/trans.png)
[英]With JSON.Net if serializing Entity Framework object, disable trips to the database
[英]json.net; serialize entity framework object (circular reference error)
我有一個實體框架實體,我想序列化為json對象。 我環顧四周,發現json.net(http://james.newtonking.com/projects/json-net.aspx)應該能夠序列化具有循環引用的對象。 所以我嘗試使用
string json = JsonConvert.SerializeObject(/* my ef entity */);
但即時通訊仍然收到相同的錯誤。 問題可能是我需要使用ReferenceLoopHandling.Ignore
和ContractResolver
,但是我不確定如何使用它們。 任何幫助深表感謝! 謝謝
為了解決這個問題,我將實體轉換為基於POCO的Code First。 為此,請在edmx窗口中右鍵單擊並選擇:
添加代碼生成項>代碼選項卡> EF POCO實體生成器。
請注意,如果看不到它,可能需要使用nuget進行安裝。
但是,在運行時,EF為跟蹤目的而向這些對象添加了代理類,但它們往往會干擾序列化過程。 為了防止這種情況,我們可以簡單地將ProxyCreationEnabled設置為false,如下所示:
var context = new YourEntities();
context.Configuration.ProxyCreationEnabled = false;
var results = context.YourEntity.Take(100).ToList();
然后,您可以通過省略默認的引用循環來安全地返回JSON.NET序列化數據,如下所示:
return JsonConvert.SerializeObject(results, Formatting.Indented,
new JsonSerializerSettings {
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
另一個解決方案是將[JsonIgnore]
屬性添加到您的導航屬性。
例如:
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; }
}
我使用以下解決方案克隆了我的實體,沒有關於實體數據屬性的技巧,並且保留了我的表循環引用。 我什至有實體互相指出,沒有任何問題。 序列化所需的庫是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
我的解決方案是簡單地刪除我的子實體上的父引用。
因此,在我的模型中,我選擇了關系並將“父代”引用更改為“內部”而不是“公共”。
可能不是所有人的理想解決方案,但對我有用。
嘗試以下操作:首先確保poco或模型具有DataContract,DataMemeber並刪除虛擬關鍵字。
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.