2010-12-19 61 views
1

alt text“将子行添加到父级的子集合”v.s. “将子项添加到datacontext的子集合中”

我会比较两个方案以添加Rsvp行。你在生产中更喜欢哪一个?


方法1:添加一个新的RSVP对象的datacontext的RSVP集合

Rsvp r = new Rsvp(); 
r.AttendeeName = "xport"; 

r.DinnerId = 1;//there will be an exception if it is set to a Dinnner object that does not exist. 

entities.Rsvps.AddObject(r); 

entities.SaveChanges(); 

如果我们尝试设置DinnerId到Dinner对象不存在,我们会得到一个异常。这种行为是一致和直接的。


方法2:添加一个新的RSVP对象到Dinner对象的回函属性

Rsvp r = new Rsvp(); 
r.AttendeeName = "xport"; 

r.DinnerId = 10000;//this Dinner does not exist! 

Dinner d = entities.Dinners.First(x => x.DinnerId == 1); 

d.Rsvps.Add(r); 

entities.SaveChanges(); 

一个RSVP对象的外键属性DinnerId可以设置为任意数量。将此Rsvp对象添加到Dinner对象的Rsvps集合时,DinnerId将被默认重写。上面的示例显示DinnerId设置为10000,它是不存在的Dinner对象的Id。这是不可避免的行为吗?

回答

2

定义方法2

为什么?因为如果没有晚餐Rsvp不能存在。在这种关系中,晚餐是父 - 如果我们要创建一个存储库中,我们将创建一个DinnerRepository(晚餐是“聚合根”在DDD而言)

在问候你的注意 - 是的,这是可以避免的行为 - 你应该做的是不要在模型上公开外键。这是您创建/更新模型时可用的选项。

这样,关系必须创建/通过实体修改:

Rsvp r = new Rsvp(); 
r.AttendeeName = "xport"; 
r.DinnerId = 10000; // this throws a compiler error. good! we do not want people tinkering with FK's. 
Dinner d = entities.Dinners.First(x => x.DinnerId == 1); 
d.Rsvps.Add(r); // this is the correct way to add a RSVP 
entities.SaveChanges(); 

换句话说 - 创建/修改RSVP是通过晚宴的唯一途径 - 与FK属性不能被修改。

这是有道理的。

+0

我认为异常将在运行时抛出,而不是在编译时抛出。对? – xport 2010-12-19 06:46:05

+1

否 - 如果您从模型中排除外键,则'Rsvp'将不会*具有名为'DinnerID'的属性 - 因此生成的类/您的POCO也不会。所以试图访问这个属性会抛出一个C#编译器错误,因为该属性不存在。这正是应该发生的事情。 – RPM1984 2010-12-19 07:16:17

+0

我应该手动排除外键吗?或者它可以在EDM向导中完成?预先感谢。 – xport 2010-12-19 07:43:27