[英]Entity Framework DBSet Include without proxies
我正在尝试创建一种使用REST Web服务的反射访问我的实体框架(首先是数据库)上下文的方法。 我已经获得了表格,并将其转换为返回列表,但是当我尝试使用Include
来获取一些相关表格时,我遇到了麻烦。
我有几个要测试的表,它们是Project和Person。 对于项目的管理人员,项目具有对人员的引用,对于人员管理的所有项目,项目均具有从人员到项目的引用。 为了使工作恢复原状,我添加了
Configuration.ProxyCreationEnabled = false;
Configuration.LazyLoadingEnabled = false;
到我的上下文的类中,以便删除引用循环,并且JSON序列化可以正常工作。
我面临的问题是我现在正在尝试显式获取所有项目以及与该项目相关的人员记录,而不包括该人员的项目列表。 但是当我尝试包含人员时,我收到JSON序列化错误,因为它拉回了循环引用。 我目前有以下代码:
Entities context = new Entities();
// Normally these will be a parameters to the calling method
string tableName = "Projects";
string includeTableName = "Person";
System.Reflection.PropertyInfo propertyInfo = context.GetType().GetProperty(tableName);
Type type = propertyInfo.PropertyType;
dynamic list = propertyInfo.GetValue(context);
var include = typeof(QueryableExtensions).GetMethod("Include", new[] { typeof(IQueryable), typeof(string) });
var toList = typeof(Enumerable).GetMethod("ToList").MakeGenericMethod(type.GenericTypeArguments[0]);
list = include.Invoke(null, new object[] { list, includeTableName });
return toList.Invoke(null, new object[] { list });
该代码可以正确执行,但随后进行调用时出现以下错误:
“,”消息“:”发生错误。“,” ExceptionMessage“:”检测到类型为'DDBAPI.EntityFramework.Project'的自引用循环。路径为[[8] .Person.Projects'。
无论如何,是否Include
可以阻止它加载循环引用? 我看到了类似的问题,这些问题涉及使DTO限制返回收益,但是由于通常我不知道要针对哪个表,因此我将不知道需要哪个DTO,因为我试图避免基于任何逻辑传入的表名。
删除代理创建并不能解决循环引用问题。 它与它无关。
仅创建代理来处理更改跟踪,但是它们具有与原始实体相同的属性。
您的问题是从表Person
到Project
都有一个导航属性,反之亦然。 这是循环引用,并且只有在删除了其中一个表中的导航属性(即Project
实体中的Person
属性或Person
实体中的Projects
属性)时,才可以破坏它。
您很可能不想这样做。 因此,您需要做的是指示序列化程序,使其可以处理循环引用。 我想您正在使用JSON.NET,它是默认情况下的当前JSON序列化程序。 我还假设您正在使用Web API。 如果是这种情况,您可以找到像这样的JSON.NET序列化器设置:
JsonSerializerSettings serializerSettings = GlobalConfiguration
.Configuration.Formatters.JsonFormatter.SerializerSettings;
然后,您需要选择以下两个选项之一:
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
。 文档在这里 。 PreserveReferencesHandling = PreserveReferencesHandling.Objects
此处的文档 。 还有另一种解决方案:您可以通过使用[JsonIgnore]
属性修饰JSON.NET来指示不对它进行序列化,而不是删除负责循环引用的导航属性之一。 文档在这里 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.