C# 在EF 6中检测到循环参考
好的,我得到这个错误: 序列化“System.Data.Entity.DynamicProxies.Asset_AED71699FAD07BF6F823A5F022DB9888F62EBBD9E422BBB11D7A191CD784288”类型的对象时检测到循环引用 我明白它的意思。我的代码是从VisualStudioTools生成的,它生成了我所有具有虚拟导航属性的POCO,并映射了关系。 我很高兴,我想懒惰的加载 下面是我的用户类的一个示例:C# 在EF 6中检测到循环参考,c#,entity-framework,json.net,C#,Entity Framework,Json.net,好的,我得到这个错误: 序列化“System.Data.Entity.DynamicProxies.Asset_AED71699FAD07BF6F823A5F022DB9888F62EBBD9E422BBB11D7A191CD784288”类型的对象时检测到循环引用 我明白它的意思。我的代码是从VisualStudioTools生成的,它生成了我所有具有虚拟导航属性的POCO,并映射了关系。 我很高兴,我想懒惰的加载 下面是我的用户类的一个示例: public partial class Use
public partial class User : IdentityUser
{
public User()
{
this.Assets = new List<Asset>();
this.Categories = new List<Category>();
this.Collections = new List<Collection>();
this.Comments = new List<Comment>();
this.LocalIntegrations = new List<LocalIntegration>();
this.Pages = new List<Page>();
this.Ratings = new List<Rating>();
this.Themes = new List<Theme>();
this.ForbiddenCategories = new List<Category>();
this.ForbiddenPages = new List<Page>();
}
public string CompanyId { get; set; }
public string CreatedById { get; set; }
public string ModifiedById { get; set; }
public System.DateTime DateCreated { get; set; }
public Nullable<System.DateTime> DateModified { get; set; }
public System.DateTime LastLoginDate { get; set; }
public string Title { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public string Email { get; set; }
public string JobTitle { get; set; }
public string Telephone { get; set; }
public string Mobile { get; set; }
public string Photo { get; set; }
public string LinkedIn { get; set; }
public string Twitter { get; set; }
public string Facebook { get; set; }
public string Google { get; set; }
public string Bio { get; set; }
public string CompanyName { get; set; }
public string CredentialId { get; set; }
public bool IsLockedOut { get; set; }
public bool IsApproved { get; set; }
public bool CanEditOwn { get; set; }
public bool CanEdit { get; set; }
public bool CanDownload { get; set; }
public bool RequiresApproval { get; set; }
public bool CanApprove { get; set; }
public bool CanSync { get; set; }
public bool AgreedTerms { get; set; }
public bool Deleted { get; set; }
public virtual Company Company { get; set; }
public virtual User CreatedBy { get; set; }
public virtual User ModifiedBy { get; set; }
public virtual ICollection<Asset> Assets { get; set; }
public virtual ICollection<Category> Categories { get; set; }
public virtual ICollection<Collection> Collections { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual ICollection<LocalIntegration> LocalIntegrations { get; set; }
public virtual ICollection<Page> Pages { get; set; }
public virtual ICollection<Rating> Ratings { get; set; }
public virtual ICollection<Theme> Themes { get; set; }
public virtual ICollection<Group> MemberOf { get; set; }
public virtual ICollection<Category> ForbiddenCategories { get; set; }
public virtual ICollection<Page> ForbiddenPages { get; set; }
}
现在我的方法是这样的:
public async Task<JsonNetResult> Get()
{
try
{
using (var service = new UserService(new CompanyService()))
{
var u = from user in await service.GetAll()
select new
{
Id = user.Id,
UserName = user.UserName,
Email = user.Email,
IsApproved = user.IsApproved,
IsLockedOut = user.IsLockedOut,
MemberOf = user.MemberOf
};
return new JsonNetResult { Data = new { success = true, users = u } }; // Return our users
}
}
catch (Exception ex)
{
return new JsonNetResult { Data = new { success = false, error = ex.Message } };
}
}
公共异步任务Get()
{
尝试
{
使用(var service=new UserService(new CompanyService()))
{
var u=来自wait service.GetAll()中的用户
选择新的
{
Id=user.Id,
UserName=user.UserName,
Email=user.Email,
IsApproved=user.IsApproved,
IsLockedOut=user.IsLockedOut,
MemberOf=user.MemberOf
};
return new JsonNetResult{Data=new{success=true,users=u};//返回我们的用户
}
}
捕获(例外情况除外)
{
返回新的JsonNetResult{Data=new{success=false,error=ex.Message};
}
}
当我运行这个程序时,我得到了和以前一样的错误,但是它显示了更多的细节。它实际上表明:
Newtonsoft.Json.Json.JsonSerializationException类型的异常在Newtonsoft.Json.dll中发生,但未在用户代码中处理
其他信息:检测到类型为“System.Data.Entity.DynamicProxies.Asset_AED71699FAD0007BF6F823A5F022DB9888F62EBBD9E422BBB11D7A191CD784288”的自引用循环。路径“用户[0]。成员[0]。公司。资产[0]。类别[0]。资产”
现在我将检查是否可以更改递归限制:(您可以尝试添加[DataContract(IsReference=true)]这将使用引用ID序列化对象,并应解决循环引用问题。根据您的更新,我将假设递归限制的当前值是问题所在。该属性的文档相对稀疏,但可以在此处找到 我相信您可以通过以下代码行替换当前的返回行来解决问题
JsonResult retVal = new JsonResult();
retVal.RecursionLimit = 1000; //maybe parameteraize this?
reVal.Data = = new { success = true, users = u };
return retVal;
编辑:更新后,我知道解决问题有多容易,因为现在由JsonConvert.SerializeObject引发异常,我以前解决过:)
根据您的更新,您可以通过更改executesult
中的一些代码来轻松解决这个问题(我对这个选项更有信心,因为我在当前项目中实际实现了它,我个人没有使用JsonResult
类,我之前的建议只是利用我对json.NET的一般知识)。您可以像下面的示例一样调用SerializeObject
重载,当您有循环引用时,它现在将抛出
string json = JsonConvert.SerializeObject(YourInstanceToSerialize, Formatting.Indented,
new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Serialize });
ReferenceLoopHandling
的可用值可在此处找到;我相信默认值是0,这就是代码抛出的原因。由于您已经使用了这些更改进行了更新,我想我建议使用第二种方法(至少我知道它会起作用),但也可以尝试第一种方法。我发现关闭这些查询的延迟加载是有效的。如果需要,只需确保您的查询通过“包含”选择所有需要的内容。
然后在查询之前:
efContext.Configuration.LazyLoadingEnabled = false;
您确定它不是来自JsonResult
类吗?我自己还没有使用过,但是json.NET有一个标志,表明是否允许循环引用,默认情况下我认为不允许JsonResult
有一个名为RecursionLimit
的属性,它很可能是同一个属性(具有循环引用的结构本质上是递归的),可能该值设置为null或0?我如何检查它是否来自JsonResult类?当我使用fiddler时,它指出问题来自System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal,这表明可能是JsonResult,因为其他所有内容都使用JSON.Net?很抱歉,响应延迟太久。我给出了一个应该能解决你问题的答案:)你找到正确的解决方法了吗?如果发现,请更新这个问题,让我知道它。
JsonResult retVal = new JsonResult();
retVal.RecursionLimit = 1000; //maybe parameteraize this?
reVal.Data = = new { success = true, users = u };
return retVal;
string json = JsonConvert.SerializeObject(YourInstanceToSerialize, Formatting.Indented,
new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Serialize });
efContext.Configuration.LazyLoadingEnabled = false;