几天来,我一直在尝试使用 Json.NET 在 EF 代码优先中保存一个复杂的实体,但没有成功。
[主要编辑和 tl;dr;:] 有没有办法将 JSON 对象反序列化为实体并保持它们的关系?
我可以用常规方式存储它。我的问题是在反序列化对象之后。
根据设计,Preference
应该添加到数据库中,但它们的Value
是外键(给出一个PreferenceValue
表(。
这是我的模型(为简洁起见,过度简化(:
public class Preference {
public virtual ICollection<PreferenceAttribute> Attributes { get; set; }
}
public class PreferenceAttribute {
public virtual ICollection<Value> Values { get; set; }
}
public class Value {
public int ValueId { get; set; }
public string Description { get; set; }
}
这些值似乎在保存之前没有附加到上下文,导致引擎存储新的Value
,而不是使用 JSON 对象提供的外键,如下所示:
{
"PreferenceAttributes":[{
"PreferenceTypeId" : 1,
"Values":[
{
"ValueId" : 1
},
{
"ValueId" : 2
},
{
"ValueId" : 3
},
]
}]
}
我可以直接在 C# 中保存它,解决任何问题;我用来播种首选项的"代码":
var attribute = new PreferenceAttribute {
AttributeId = 1,
Values = context.Values.OrderBy(a => a.ValueId).Skip(1).Take(5).ToList();
};
var preferece = new Preference {
Attributes = new List<PreferenceAttribute> {
attribute
}
};
//user is fetched from "context" as well
user.Preferences.Add(preferece);
context.SaveChanges();
请记住,这只是关于Value
。如前所述,问题是新的Value
正在添加到数据库中,而不是使用它们的Id
作为外键来与PrefferenceAttribute
s相关联,即EF认为我想添加新的Value
,如下所示:
attribute.Values = new List<Value> {
new Value {
ValueId = 1, //This id will be ignored by EF since it's not fetched using context; new record will be inserted;
WhateverAttributes = "WTF"
}
}
此致敬意。
我认为您的问题是现有记录没有引用外键记录,而是新创建和引用的。
我认为出现此问题是因为您的所有实体都处于"已添加"状态。您可能希望外键记录处于"未更改"状态。查看此链接以了解实体状态 http://msdn.microsoft.com/en-us/data/jj592676.aspx
首先,我建议您将域模型与Dto分开。执行此操作后,您将在清除外键记录之前手动解析外键记录。