解決Newtonsoft.json將資料庫實體表序列化為json時提示此例項已被釋放的錯誤
阿新 • • 發佈:2019-02-05
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轉換如下:
H_MES_USERS的ID是H_MES_USERROLE表的UserID欄位的外來鍵。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; } }
出現此錯誤的原因是被序列化的資料庫表與其他表有外來鍵的關係,你用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);
這兩個屬性我都試過了,好像都沒效果。