EF - 对分离对象的持久性忽略 - 最佳实践

时间:2014-07-20 14:43:22

标签: c# entity-framework entity persistence-ignorance

现在我根本无法理解持久性无知如何应用于实体框架。 我使用实体框架设计了经典的存储库和工作单元。

现在,想象一个简单的客户端方案,我需要读取一些对象列表,然后保存其中一个。 我的实体包含一些对象图,例如,Person实体coontains地址复杂属性,其中Addrress是另一个实体,也是一个Hobby对象列表,它也是另一个实体。 我的客户:

var personList = PersonRepository.GetAll();
PersonRepository.Dispose(); // it will dispose EF's ObjectContext 
var person = personList[0];
person.Address.City = "...";
person.Hobby.Remove(person.Hobby.First());
PersonRepository.SaveChanges(person);

正如你所看到的,我已经保留了持久性无知逻辑,我只限于使用人物对象及其边界,但是,在现实世界中,上面的代码片段将倾向于失败分离对象因为我已经处理了工作单元。

所以,我已经想过用一些方法来使用一些实体包装器 ManageGraph(对象obj,ObjectState状态),以便为所有关系更改保留内部字典中的任何其他更改。但是,我不喜欢这个解决方案,看起来太脏了,看起来像anty模式:

person.Name = "some name";
person.ManageGraph(AddressObject, state.Modified);
rather then
person.ManageGraph(AddressObject, state.Added);

但是......坚持无知在哪里?为什么我会强制使用不良技巧来获得正确的工作?持久性无知意味着我必须在没有任何其他东西的情况下对待简单对象,所以它就像是:

person.SomeProperty = SomeValue
person.ComplexProperty.OtherProperty = otherValue
person.ListOfComplexProperty.Add(new entity);

当然,我知道,我不想要神奇的解决方案,它不存在,但是,是否有一些很好的解决方案或建议可以获得最佳效果?

1 个答案:

答案 0 :(得分:1)

您没有分离您的实体,您只是处理上下文。这意味着您的实体不再被任何有效的上下文“更改跟踪”。当你从一个新的上下文调用SaveChanges方法时,操作失败并且你没有异常(这是可以的,因为实体在内存中但根本没有任何跟踪,对于新的上下文,它不存在)。在处理上下文之前,您应该Detach实体,然后,在退出方法时,将其附加回新上下文。如果你正在使用DbContext,也许你应该看看这个article

然而,坚持无知是一个指导原则。使用实际语言,几乎不可能达到。你最好的朋友是存储库模式和工作单元。他们将通过实现抽象将您的业务代码与上下文分离,并将这种与持久性相关的东西“隐藏”到业务代码中。我建议您不要在乎在业务代码中分离您的实体。如果你绝对需要它(?),也许你应该在存储库级别这样做。从业务代码中管理上下文生命周期是一种糟糕的方法,您应该将此逻辑保留在repo / UoW层中。

希望这有帮助,