EF 序列化实体为Json时的循环引用问题(不用自己写实体,不用匿名类型,不用EF的上下文属性)
自己写实体可以完美解决这个问题。(支持时间格式自定义)
用匿名类型也可以。
设置上下文方法如下:
(jz为数据库上下文对象)
jz.Configuration.ProxyCreationEnabled = false;
jz.Configuration.LazyLoadingEnabled = false;
不用这个的原因是Virtual属性也会生成。(只是占个位,[]里面没内容,但看着不爽)
我采用的方法是过滤掉Virtual属性的方法:
一个基于Json.net的类
1 | using Newtonsoft.Json;<br> using Newtonsoft.Json.Converters;<br> using Newtonsoft.Json.Serialization;<br> using System;<br> using System.Collections.Generic;<br> using System.Linq;<br> using System.Reflection;<br> using System.Web;<br><br> namespace AceepSystem.Models.Help<br>{<br> public class JsonForEF : DefaultContractResolver<br> {<br> string [] props = null ;<br><br> bool retain;<br><br> /// <summary><br> /// 构造函数<br> /// </summary><br> /// <param name="props">传入的属性数组</param><br> /// <param name="retain">true:表示props是需要保留的字段 false:表示props是要排除的字段</param><br> public JsonForEF(string[] props, bool retain = true)<br> {<br> //指定要序列化属性的清单<br> this.props = props;<br><br> this.retain = retain;<br> }<br><br> protected override IList<JsonProperty> CreateProperties(Type type,<br><br> MemberSerialization memberSerialization)<br> {<br> IList<JsonProperty> list =<br> base.CreateProperties(type, memberSerialization);<br> //只保留清单有列出的属性<br> return list.Where(p =><br> {<br> if (retain)<br> {<br> return props.Contains(p.PropertyName);<br> }<br> else<br> {<br> return !props.Contains(p.PropertyName);<br> }<br> }).ToList();<br> }<br> public static string[] GetVirtualList<T>()<br> {<br> var stringType = typeof(T);<br> var props = stringType.GetProperties();<br> List<string> test = new List<string>();<br> foreach (var prop in props)<br> {<br> if (prop.GetAccessors()[0].IsVirtual)<br> {<br> test.Add(prop.Name);<br> }<br> }<br> return test.ToArray();<br> }<br> public static JsonSerializerSettings GetJsonConfig<T>()<br> {<br><br> JsonSerializerSettings jsetting = new JsonSerializerSettings();//过滤掉ef中的导航属性,无残留...<br> jsetting.ContractResolver = new JsonForEF(<br> JsonForEF.GetVirtualList<T>()//泛型方法传入当前要序列化的类型<br> , false);//false为要排除的属性,true为要保留的属性(第一个参数为string[])<br> jsetting.Converters.Add(new MyDateTimeConvertor());<br> return jsetting;<br> }<br> public class MyDateTimeConvertor : DateTimeConverterBase<br> {<br> public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)<br> {<br> return DateTime.Parse(reader.Value.ToString());<br> }<br><br> public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)<br> {<br> writer.WriteValue(((DateTime)value).ToString("yyyy/MM/dd HH:mm"));<br> }<br> }<br> }<br>} |
和一个对PropertyInfo的扩展方法
1 | using System;<br> using System.Collections.Generic;<br> using System.Linq;<br> using System.Reflection;<br> using System.Web;<br><br> namespace AceepSystem.Models.Help<br>{<br> public static class Virtual_Help<br> {<br> <br> public static bool ? IsVirtual( this PropertyInfo self)<br> {<br> if (self == null )<br> throw new ArgumentNullException( "self" );<br><br> bool ? found = null ;<br><br> foreach (MethodInfo method in self.GetAccessors())<br> {<br> if (found.HasValue)<br> {<br> if (found.Value != method.IsVirtual)<br> return null ;<br> }<br> else <br> {<br> found = method.IsVirtual;<br> }<br> }<br><br> return found;<br> }<br> <br> }<br>} |
使用方法如下
string json = JsonConvert.SerializeObject(
list,
Formatting.Indented,
JsonForEF.GetJsonConfig<dic_attribution>()
);//转C#对象为Json数据
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
2015-03-31 又看了半天的pdf格式的js方面的书,感觉受益匪浅啊,只会一点操作的我,要学好理论
2015-03-31 作为刚入职个把星期的小白,表示公司的项目就是复制粘贴,表示很迷茫,这样的话怎么成大牛哇?