EntityFramework中JSON序列化循环引用----JavaScriptSerializer

一、JavaScriptSerializer

JavaScriptSerializer是ASP.Net 自带的JSON序列化和反序列化工具,例如:MVC中的JsonResult也是使用的它。

位于:程序集 System.Web.Extensions 中

namespace System.Web.Script.Serialization
{
    //
    // 摘要:
    //     为启用 AFAX 的应用程序提供序列化和反序列化功能。
    public class JavaScriptSerializer

二、[ScriptIgnore] 用于指定在序列化对象时忽略的属性

特别说明:如果该属性在父类中重写,需要在父类中的属性重新指定。

namespace System.Web.Script.Serialization
{
    //
    // 摘要:
    //     指定 System.Web.Script.Serialization.JavaScriptSerializer 不序列化公共属性或公共字段。 此类不能被继承。
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
    public sealed class ScriptIgnoreAttribute : Attribute
    {

三、EF中json序列化的循环引用

1.在表关联显示指定主外键关系中会出现循环引用问题

2.在表自连接的主外键关系中会出现循环引用问题

3.在EF中指定[ScriptIgnore],需要去掉属性的virtual关键词,以为从数据库查处来的对象时继承关系的动态对象。

4.特别说明:在EF中的一对多关联列表的virtual关键词,则获取关联表数据失败。所以对于自引用类如果使用JavaScriptSerializer序列化去掉向下查找列表的功能

以自引用为实例说明:


实体类:

[Table("Area")]
public partial class Area
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Area()
    {
        Children = new HashSet<Area>();
    }

    public int AreaID { get; set; }

    [Required]
    [StringLength(20)]
    public string AreaName { get; set; }

    public int? ParentID { get; set; }

    public int? SortValue { get; set; }

    public int AreaLevel { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    [ScriptIgnore]
    public  ICollection<Area> Children { get; set; } //特别说明:如果向下集合去掉virtual,向下查询将不可用

    [ScriptIgnore]
    [ForeignKey("ParentID")]
    public Area ParentModel { get; set; } //特别说明:如果使用[ScriptIgnore] 需要去掉virtual声明
}
测试代码:

static void EfTest1()
{
    Test1 _context = new Test1();
    JavaScriptSerializer _ser = new JavaScriptSerializer();
    //获取省
    Area province = _context.Areas.FirstOrDefault(q => q.AreaLevel == 1);
    Console.WriteLine(_ser.Serialize(province));
    //获取省下的市
    List<Area> cities = province.Children.ToList();
    Console.WriteLine(cities.Count);
    Console.WriteLine(_ser.Serialize(cities));

    //获取市
    Area city = _context.Areas.FirstOrDefault(q => q.AreaLevel == 2);
    Console.WriteLine(_ser.Serialize(city));
    //获取市所在的省
    Area province2 = city.ParentModel;
    Console.WriteLine(_ser.Serialize(province2));
}


四、对于EF中的Json序列化推荐使用Newtonsoft

原因:Newtonsoft中提供了忽略循环引用的处理,枚举定义:ReferenceLoopHandling.Ignore,

这样就不需要修改实体类的代码,并且向下查找列表也可用。

static void EfTest2()
{
    Test1 _context = new Test1();
    JsonSerializerSettings settings = new JsonSerializerSettings();
    settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    //获取省
    Area province = _context.Areas.FirstOrDefault(q => q.AreaLevel == 1);
    Console.WriteLine(JsonConvert.SerializeObject(province, settings));
    //获取省下的市
    List<Area> cities = province.Children.ToList();
    Console.WriteLine(JsonConvert.SerializeObject(cities, settings));

    //获取市
    Area city = _context.Areas.FirstOrDefault(q => q.AreaLevel == 2);
    Console.WriteLine(JsonConvert.SerializeObject(cities, settings));
    //获取市所在的省
    Area province2 = city.ParentModel;
    Console.WriteLine(JsonConvert.SerializeObject(province2, settings));
}

获取省对象结果:对象类型

{
    "Children": [
        {
            "Children": [],
            "AreaID": 2,
            "AreaName": "济南市",
            "ParentID": 1,
            "SortValue": null,
            "AreaLevel": 2
        }
    ],
    "ParentModel": null,
    "AreaID": 1,
    "AreaName": "山东省",
    "ParentID": null,
    "SortValue": null,
    "AreaLevel": 1
}
获取省下的市列表:数组类型

[
    {
        "Children": [],
        "ParentModel": {
            "Children": [],
            "ParentModel": null,
            "AreaID": 1,
            "AreaName": "山东省",
            "ParentID": null,
            "SortValue": null,
            "AreaLevel": 1
        },
        "AreaID": 2,
        "AreaName": "济南市",
        "ParentID": 1,
        "SortValue": null,
        "AreaLevel": 2
    }
]

更多: 

EntityFramework中Json序列化的循环引用问题解决--Newtonsoft.Json

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值