我有以下课程:
public class item
{
public int NodeID
{
get ;
set ;
}
public int Weight
{
get ;
set ;
}
public int Category
{
get ;
set ;
}
}
public class Recipients
{
public int RecipientID
{
get ; set;
}
}
public class Nodes
{
public List<int> RecipientList
{
get ;
set ;
}
public item Item
{
get ; set;
}
public int Capacity
{
get ; set;
}
public int NodeID
{
get ; set;
}
public int Weight
{
get ; set;
}
public int Category
{
get ; set;
}
}
我尝试将其保存在具有以下表格的现有数据库中:
1) Category
2) Items
3) Nodes (Node and Items has 1-1 relationship)
4) Recipients
5) NodeRecipients (This table show the many to many relationship between Nodes and Recipients)
我使用VS2012创建EF模型,如下图所示(请注意,节点源自EF中的项目)
我有一种尝试保存节点及其收件人的方法
public void SaveNodeAndRecipient(List<Nodes> MyNodes)
{
using (var db = new MyEntities())
{
foreach (var n in MyNodes)
{
Node n1 = new Node() { NodeID = n.NodeID, categoryID = n.Category, Capacity = n.Capacity };
db.Items.Add(n1);
foreach (var r in n.RecipientList)
{
Recipient rep;
if (!db.Recipients.Select(x => x.recipientID).Contains(r))
{
rep = new Recipient() { recipientID = r };
db.Recipients.Add(rep);
}
else
{
rep = db.Recipients.Where(x => x.recipientID == r).FirstOrDefault();
}
Node_Recipient nr = new Node_Recipient(){RecipientID=r,NodeID=n.NodeID};
n1.Node_Recipient.Add(nr);
}
}
db.SaveChanges();
}
}
MyEntities是EF模型,在appconfig中声明:
<connectionStrings>
<add name="MyEntities" connectionString="xxxxx" providerName="System.Data.EntityClient" />
</connectionStrings>
在我尝试保存更改之前,一切都很好并且编译没有问题。我收到了这个错误(不是很具描述性)
任何人都知道发生了什么事?我的印象是,多对多关系是罪魁祸首,但无法确定导致它的原因。 请帮忙!
答案 0 :(得分:3)
问题是您正在设置Node_Recipient.recipientID
值,但根据您的说明,我非常确定这些主键值是由数据库生成的。因此,无法保证在保存对象时将存在值(r
)。
更糟糕的是 - 新的Recipients
甚至不太可能保留指定的r
值,因此您可能会创建错误的关联。
这是应该适合你的。请参阅下面的一些评论。
foreach (var n in MyNodes)
{
Node n1 = new Node {
NodeID = n.NodeID,
categoryID = n.Category,
Capacity = n.Capacity
};
foreach (var r in n.RecipientList)
{
Recipient rep = db.Recipients.Find(r);
if (rep == null)
{
rep = new Recipient(); // see comment 1.
}
Node_Recipient nr = new Node_Recipient {
Recipient = rep,
Node = n1
// See comment 2
};
n1.Node_Recipient.Add(nr);
}
db.Items.Add(n1); // see comment 3
}
此处未设置recipientId
。
在此设置引用而不是ID
值。 EF会在保存更改的同时“及时”分配正确的外键值。
这会将新Node
下的对象图中的所有对象标记为Added
,除非他们已经了解了上下文,这对于您找到的Recipients
是正确的db.Recipients.Find(r)
。
对于多对多关联,表Node_Recipient
看起来像纯粹的联结表,即只有两个外键的表。必须有一个原因,为什么EF没有生成具有透明m:n关联的模型,没有Node_Recipient
实体。通常它会这样做。生成模型时,Node_Recipient
是否包含您稍后删除的其他列?
如果您想要此m:n关联,您可能需要尝试重新生成模型。这应该会生成Nodes
类,其中Recipients
集合和Recipient
集合Nodes
。然后,设置关联就是将新收件人添加到Node.Recipients
。
答案 1 :(得分:0)
只是查看你的代码,没有异常细节,我想知道在将n1
添加到数据库之前是否需要对Node n1 = new Node() { NodeID = n.NodeID, categoryID = n.Category, Capacity = n.Capacity };
foreach (var r in n.RecipientList)
{
if (db.Recipients.Where(x => x.recipientID == r).FirstOrDefault() == null)
{
Recipient rep = new Recipient() { recipientID = r };
db.Recipients.Add(rep);
}
Node_Recipient nr = new Node_Recipient(){RecipientID=r,NodeID=n.NodeID};
n1.Node_Recipient.Add(nr);
}
db.Items.Add(n1); // add here, after modifications to n1
进行修改:
{{1}}