2011-11-02 100 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 
相关问题