我有一个使用Hot Towel模板的ASP.Net MVC SPA,即breezejs,knockout,实体框架(代码优先),durandal等。
在我的EF模型中,我有一个名为“Section”的类,它具有自引用关联。每个部分属于“文档”,每个部分也有一个“项目”集合:
public class Section : CommonBase
{
...
public Guid DocumentId { get; set; }
public Document Document { get; set; }
...
public List<Item> Items { get; set; }
public Guid? ParentId { get; set; }
public Section Parent { get; set; }
public List<Section> Children { get; set; }
...
}
public class Item : CommonBase
{
...
public Guid SectionId { get; set; }
public Section Section { get; set; }
...
}
当我通过Breeze查询和BreezeController方法加载文档时,我加载了“Sections”和“Items”:
var query = breeze.EntityQuery.from(model.entitySets.document)
.where(predicate)
.expand("sections.items.cloudDriveFile, sections.cloudDriveFile")
.orderBy(model.orderByClauses.document);
return _contextProvider.Context.Documents.Where(x => x.OrganisationId == currentUser.OrganisationId);
如果我编辑并保存“部分”而不加载任何“项目”,那么一切正常。但是当我尝试编辑并保存一个包含“Items”的部分时 - 我已经加载了那些“Items”(使用BreezeController中的Include或javascript中的扩展) - 然后我收到以下错误:
“未捕获的TypeError:将循环结构转换为JSON”
我正在使用对manager.saveChanges()的简单调用进行保存。
我是否应该采用一些技术或模式来避免这种循环引用错误?
答案 0 :(得分:0)
不确定您的EF型号是代码优先还是数据库优先,但如果代码优先我没有看到您的任何属性entityModel与定义ForeignKey属性有关。如果数据库优先,请确保启用了外键关联。以下链接可能会提供更多信息:Navigation properties,Server side model
答案 1 :(得分:0)
您可以通过急切加载儿童来解决此问题。
从公共虚拟列表子项中删除虚拟
答案 2 :(得分:0)
经过进一步调查后,我发现每当我尝试将更改保存到已加载相关集合的对象(即导航属性的内容)时,就会发生同样的问题,其中集合中的对象随后返回参考到了父母。我将错误跟踪到breeze.debug.js(版本1.3.5)中的以下行:
var bundle = JSON.stringify(saveBundle);
我发现如果我用以下内容替换此行(根据JSON.stringify, avoid TypeError: Converting circular structure to JSON),则不再出现错误:
var cache = [];
var bundle = JSON.stringify(saveBundle, function (key, value) {
if (typeof value === 'object' && value !== null) {
if (cache.indexOf(value) !== -1) {
// Circular reference found, discard key
return;
}
// Store value in our collection
cache.push(value);
}
return value;
});
cache = null; // Enable garbage collection
虽然这解决了我当前的问题,但我觉得必须有另一种方法 - 当然我不能成为唯一一个试图在这种情况下保存更改的人。