赞
踩
Newtonsoft.json版本:10.0.0.0
数据库:sqlserver2008r2
Entity Framework版本:5.0.0
EF查询语句如下:
- public DBResult<List<H_MES_USERS>> GetUsers()
- {
- DBResult<List<H_MES_USERS>> Result = new DBResult<List<H_MES_USERS>>();
- try
- {
- using (HCN_M_DATAEntities entities = new HCN_M_DATAEntities())
- {
- Result.Data = entities.H_MES_USERS.ToList();
- Result.Success = true;
- }
- }
- catch (Exception ex)
- {
- WriteLog.WriteLogFile(this.GetType(), LogLevel.ERROR, ex.ToString());
- }
-
- return Result;
- }

JSON转换如下:
- public static string ObjToJson<T>(T obj)
- {
- try
- {
- return JsonConvert.SerializeObject(obj);
- }
- catch (Exception ex)
- {
- WriteLog.WriteLogFile(typeof(NewtonJsonConvert), LogLevel.ERROR, ex.ToString());
- return null;
- }
- }
H_MES_USERS的ID是H_MES_USERROLE表的UserID字段的外键。
出现此错误的原因是被序列化的数据库表与其他表有外键的关系,你用EF查询H_MES_USERS,EF会建立与H_MES_USERROLE表的映射关系,这种映射关系是基于数据库中的外键建立的。也就是说当序列化JSON在using (HCN_M_DATAEntities entities = new HCN_M_DATAEntities())这个范围内时,JsonConvert.SerializeObject这个函数就可以找到这种映射关系,即可以完成序列化。当在这个范围外序列号时,因为数据库的连接已经关闭了,所以无法找到这种映射关系,才会提示此实例已被释放的错误。
解决的方法有两种:
1、在自动生成的EF实体类H_MES_USERS的 H_MES_USERROLE 属性上添加[JsonIgnore]特性。
- [JsonIgnore]
- public virtual ICollection<H_MES_USERROLE> H_MES_USERROLE { get; set; }
当然还必须在实体类H_MES_USERS中添加using Newtonsoft.Json;
这种方式的告诉JSON转换器不用去管外键的映射关系。
2、
entities.H_MES_USERS.ToList().Select(u => new H_MES_USERS() { ID = u.ID,UserName = u.UserName}).ToList();
当你只需要H_MES_USERS中的几个字段时,可以在select里面new一个H_MES_USERS对象,此时的H_MES_USERS对象只是一个实体类,与H_MES_USERROLE表的映射关系也没有了,所以序列化JSON的时候就不会去查询映射关系。
关于网上流传的在做JSON转换的时候设置参数,这种方式为也是过了,好像没什么用,代码如下:
- JsonSerializerSettings setting = new JsonSerializerSettings();
- setting.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
- setting.MissingMemberHandling = MissingMemberHandling.Ignore;
- return JsonConvert.SerializeObject(obj,setting);
这两个属性我都试过了,好像都没效果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。