我有以下课程:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试将其保存在具有以下表格的现有数据库中:
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)
Run Code Online (Sandbox Code Playgroud)
我使用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();
}
}
Run Code Online (Sandbox Code Playgroud)
MyEntities是EF模型,并在appconfig中声明:
<connectionStrings>
<add name="MyEntities" connectionString="xxxxx" providerName="System.Data.EntityClient" />
</connectionStrings>
Run Code Online (Sandbox Code Playgroud)
一切都很好,编译没有问题,直到我试图保存更改.我收到了这个错误(不是很具描述性)
谁知道发生了什么事?我的印象是,多对多关系是罪魁祸首,但无法确定导致它的原因.请帮忙!
问题是您正在设置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
}
Run Code Online (Sandbox Code Playgroud)
这里没有recipientId
设置。
您可以在此处设置引用而不是值ID
。EF 将在保存更改时“及时”分配正确的外键值。
这会将对象图中的所有对象标记为 new 下的对象Node
,Added
除非它们已经为上下文所知,这对于您Recipients
通过 找到的对象来说是正确的db.Recipients.Find(r)
。
对于多对多关联,该表Node_Recipient
看起来像一个纯粹的联结表,即只有两个外键的表。EF 没有生成具有透明 m:n 关联且没有Node_Recipient
实体的模型,肯定是有原因的。通常情况下它会这样做。当您生成模型时,是否Node_Recipient
包含您后来删除的其他列?
如果您想要这种 m:n 关联,您可能需要尝试重新生成模型。这应该生成一个Nodes
带有集合的类Recipients
和一个Recipient
带有Nodes
集合的类。设置关联就是向 中添加新收件人的问题Node.Recipients
。
归档时间: |
|
查看次数: |
212 次 |
最近记录: |