[英]Deleting a child entity in a many-to-one relationship using POCO in EF4 CTP5
简洁版本:
使用经典的Order和OrderLine示例,如何在POCO中执行以下操作:
public partial class Order {
public void RemoveInvalidOrderLines() {
OrderLines.Remove(OrderLines.Where(ol => ol.Quantity > MaxQuantity));
}
}
在使用POCO的多对一关系中,这仅删除OrderLine中对Order的引用。 有没有办法自动删除OrderLine实体? 或者我是否必须注入存储库或将代码提升到服务中? 在数据库中使用触发器? 这有什么模式或最佳实践吗? 我在网上找到的所有例子似乎都使用了一些简单的添加和“这就是你应该使用POCO的原因”:-)
情况:
在VS2010中使用EF4 CTP5,生成持久性无知的POCO(动态代理),我在如何处理删除相关的“子”实体方面遇到了困难。
问题:下面的Employee类中的ICollection Relative中的Remove方法仅删除关系,而不删除最终实体。 有没有办法强制它删除实体,而无需注入存储库/服务或从实体中提取代码? 我想要一个干净的POCO类。
动机:没有员工,相对实体不可能存在,因此处理添加,删除等最自然的地方是在Employee类中。 再说一遍,我愿意接受建议。 :-)
示例:一个员工可以拥有多个亲戚。 Employee类有一个存储库,提供常用的查找程序。 我希望Employee能够删除亲属,而不仅仅是FK关系。 我是否必须注入存储库或类似物才能执行此操作? 我试图将上下文和存储库保留在POCO之外。
假设以下表格:
Employee:
Id int (PK, not null)
Name varchar
Relative:
Id int (PK, not null)
EmployeeId int (FK, not null)
Name varchar
生成以下POCO:
public partial class Employee {
...
public virtual ICollection<Relative> Relatives
{
get
{
if (_relatives == null)
{
var newCollection = new FixupCollection<Relative>();
newCollection.CollectionChanged += FixupRelatives;
_relatives = newCollection;
}
return _relatives;
}
set
{
if (!ReferenceEquals(_relatives, value))
{
var previousValue = _relatives as FixupCollection<Relative>;
if (previousValue != null)
{
previousValue.CollectionChanged -= FixupRelatives;
}
_relatives = value;
var newValue = value as FixupCollection<Relative>;
if (newValue != null)
{
newValue.CollectionChanged += FixupRelatives;
}
}
}
}
而且当然,
Relative:
public partial class Relative {
...
public virtual Employee Employee
{
get { return _employee; }
set
{
if (!ReferenceEquals(_employee, value))
{
var previousValue = _employee;
_employee = value;
FixupEmployee(previousValue);
}
}
}
private Employee _employee;
}
现在,人们可以这样做:
var employeeRepository = new EmployeeRepository(dbContext);
var employee = employeeRepository.Get(1234);
var relative = new Relative { Name = "Lars" };
employee.Relatives.Add(relative);
context.SaveChanges();
并将相对内容添加到Relative表中,并引用该员工。
但是,如果我想在Employee-class中实现DeleteRelative方法:
public void DeleteRelative(string name) {
Relatives.Remove(Relatives.FirstOrDefault());
}
(天真的代码假设亲戚存在等)
我明白了:
System.InvalidOperationException: The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
这是完全可以理解的,因为Relative中的EmployeeId字段不能为null。
因此,除了将存储库/上下文注入到实体中之外,还有可能以任何方式解决这个问题(恕我直言,这种方式违背了POCO的目的)。
另一种方法是将它全部包装在服务或事务脚本中,但同样,我希望EF4能够在没有配置/连接实体或执行事务脚本的情况下处理这个问题。
非常感谢任何帮助,如果您需要更多信息,请告诉我。
哦,祝大家新年快乐。 :-)
如果它是应用程序架构中的一个选项,您可以考虑在您的实体上启用动态代理。 这使上下文能够创建实体的子类,从而覆盖您的属性以跟踪更改。 在您的情况下,当对象丢失它的引用时,这将删除与您的对象相对应的行(假设您在上下文中调用SaveChanges())。
可以在启用动态代理时启用
看看这个问题,你似乎满足了这些要求。
启用动态代理可以通过在上下文中设置属性来完成(也可以在Entity Framework设计器视图中完成):
this.ContextOptions.ProxyCreationEnabled = true;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.