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

本文关键字:最佳 对象 持久化 分离 | 更新日期: 2023-09-27 18:13:58

现在我完全不能理解持久性的无知是如何应用于实体框架的。我用实体框架设计了一个经典的存储库和工作单元。

现在,想象一个简单的客户端场景,我需要读取一些对象列表,然后保存其中一个。我的实体包含一些对象图,例如,Person实体包含Address复杂属性,其中Address是另一个实体,还包含一个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);

正如您所看到的,我已经维护了持久化忽略逻辑,我被限制只使用person对象及其边界,然而,在现实世界中,上面的代码片段将倾向于分离对象失败,因为我已经处理了工作单元。

所以,我想使用一些实体包装与一些方法,如ManageGraph(object obj, ObjectState state),以便在内部字典中保存所有关系更改的任何其他更改。然而,我不喜欢这个解决方案,它看起来太脏了,看起来像一个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);

当然,我知道,我不想要神奇的解决方案,它不存在,但是,有没有一些好的解决方案或建议来获得最好的工作?

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

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

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

希望有帮助,