2016-03-16 163 views
0

我想创建一个访问我的实体框架(数据库优先)上下文使用REST Web服务的反射的方法。我已经得到了表,并将其转换为返回列表,但当我尝试使用Include获取某些相关表时,我遇到了麻烦。实体框架DBSet包含无代理

我有几个表,我正在测试,他们是项目和人员。项目对管理项目的人员提供人员参考,并为个人管理的所有项目提供人员对项目的参考。为了获得原始复工我加

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 }); 

代码执行正常,但后来我打这个电话,我得到了以下错误:

"Message":"An error has occurred.","ExceptionMessage":"Self referencing loop detected with type 'DDBAPI.EntityFramework.Project'. Path '[8].Person.Projects'."

反正是有与Include从加载循环引用阻止它?我看到了类似的问题,这些问题引用了DTO来限制什么被拉入回报,但是因为通常我不会知道我将调用哪张表,我不知道哪个DTO是我需要的,因为我试图避免任何基于周围的逻辑表名被传入。

回答

1

删除代理创建不能解决循环引用问题。它与它无关。

只是创建代理来处理更改跟踪,但它们具有与原始实体相同的属性。

你的问题是有一个导航属性从表PersonProject反之亦然。这是循环引用,如果您删除其中一个表中的导航属性(即Project实体中的Person属性或Person实体中的Projects属性),则只能将其分开。

很可能你不想这样做。所以,你需要做的是指示串行器,以便它可以处理循环引用。我想你使用的是JSON.NET,默认情况下它是当前的JSON序列化程序。我也假设你正在使用Web API。如果是这样的话,你可以找到这样的JSON.NET串行器设置:

JsonSerializerSettings serializerSettings = GlobalConfiguration 
    .Configuration.Formatters.JsonFormatter.SerializerSettings; 

然后,你需要选择这两个选项之一:

  • ReferenceLoopHandling = ReferenceLoopHandling.IgnoreDocs here
  • PreserveReferencesHandling = PreserveReferencesHandling.ObjectsDocs here

还有另一种解决方案:代替去除负责循环引用的导航属性之一,可以指示JSON.NET到不受与[JsonIgnore]属性装饰它序列化。 Docs here

+0

感谢您的帮助。我用'ReferenceLoopHandling = ReferenceLoopHandling.Ignore'去了,它现在的表现完全如您所愿。 –