EF 序列化实体为Json时的循环引用问题(不用自己写实体,不用匿名类型,不用EF的上下文属性)

Posted 小小高

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EF 序列化实体为Json时的循环引用问题(不用自己写实体,不用匿名类型,不用EF的上下文属性)相关的知识,希望对你有一定的参考价值。

自己写实体可以完美解决这个问题。

用匿名类型也可以。

设置上下文方法如下:

(jz为数据库上下文对象)

jz.Configuration.ProxyCreationEnabled = false;
jz.Configuration.LazyLoadingEnabled = false;

不用这个的原因是Virtual属性也会生成。(只是占个位,[]里面没内容,但看着不爽)

我采用的方法是过滤掉Virtual属性的方法:

一个基于Json.net的类

public class LimitPropsContractResolver : DefaultContractResolver
    {
        string[] props = null;

        bool retain;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="props">传入的属性数组</param>
        /// <param name="retain">true:表示props是需要保留的字段  false:表示props是要排除的字段</param>
        public LimitPropsContractResolver(string[] props, bool retain = true)
        {
            //指定要序列化属性的清单
            this.props = props;

            this.retain = retain;
        }

        protected override IList<JsonProperty> CreateProperties(Type type,

        MemberSerialization memberSerialization)
        {
            IList<JsonProperty> list =
            base.CreateProperties(type, memberSerialization);
            //只保留清单有列出的属性
            return list.Where(p =>
            {
                if (retain)
                {
                    return props.Contains(p.PropertyName);
                }
                else
                {
                    return !props.Contains(p.PropertyName);
                }
            }).ToList();
        }
        public static string[] GetVirtualList<T>()
        {
            var stringType = typeof(T);
            var props = stringType.GetProperties();
            List<string> test = new List<string>();
            foreach (var prop in props)
            {
                if (prop.GetAccessors()[0].IsVirtual)
                {
                    test.Add(prop.Name);
                }
            }
            return test.ToArray();
        }
    }

 和一个对PropertyInfo的扩展方法

public static class Virtual_Help
    {
      
        public static bool? IsVirtual(this PropertyInfo self)
        {
            if (self == null)
                throw new ArgumentNullException("self");

            bool? found = null;

            foreach (MethodInfo method in self.GetAccessors())
            {
                if (found.HasValue)
                {
                    if (found.Value != method.IsVirtual)
                        return null;
                }
                else
                {
                    found = method.IsVirtual;
                }
            }

            return found;
        }
       
    }

 使用方法如下

 JsonSerializerSettings jsetting = new JsonSerializerSettings();
            jsetting.ContractResolver = new LimitPropsContractResolver(
            LimitPropsContractResolver.GetVirtualList<affairs>(), false);
            string json = JsonConvert.SerializeObject(temp, Formatting.Indented, jsetting);

 

以上是关于EF 序列化实体为Json时的循环引用问题(不用自己写实体,不用匿名类型,不用EF的上下文属性)的主要内容,如果未能解决你的问题,请参考以下文章

实体框架导致循环引用?

解决MVC Json序列化的循环引用问题/EF Json序列化循引用问题---Newtonsoft.Json

解决MVC Json序列化的循环引用问题/EF Json序列化循引用问题---Newtonsoft.Json

EF 将实体序列化为包含相关实体的 json 创建一个循环

EF中Json序列化对象时检测到循环引用的解决办法

EF实体类,设置导航属性,导致序列化时出现"循环引用"错误,及序列化时间格式解决方案