6

可能重复:
持久无知有什么好处?

经过一段时间和一些试图弄清楚实体框架的问题后,我得出的结论是,我只是不明白持久性无知对象的意义是什么。

据我所知,使用持久性感知对象和持久性无知对象之间的实际区别在于,使用的对象类似于

Person p = Person.Load(id);
p.Active = false;
p.Save();

另一个是沿线使用

using (var context = new MyContext())
{
   Person p = context.Persons.Single(x => x.ID == id);
   p.Active = false;
   context.SaveChanges();
}

在第一种情况下,我可以返回p,并Save()在稍后调用。在后者中,我可以 return p,但我需要将它放入一个 newMyContext()中以保存它。在第一种情况下,假设 Person 从实际处理数据库逻辑的某个基础对象继承 Load() 和 Save(),如果我想更改持久性,它只涉及更改该基础对象(甚至只是有一个IPersistent接口可以实现多个基类来访问多个商店)。在后者中,如果持久层发生更改,我将需要更改每个实例MyContext,并且零碎做会非常复杂。

我的印象是坚持-无知是件好事。我只是不明白为什么。似乎设置、使用、更改批发和零碎更改要复杂得多,这种复杂性没有任何优势。我只是错过了一些重要的事情,还是我对持久意识/无知意味着什么的整个理解有缺陷?

4

2 回答 2

5

持久性无知是关注点分离的一部分。您应该问自己,为什么 Person 应该知道应该如何加载或保存它?人应该处理自己的小领域。

PI 意味着 Person 不关心它是否来自内存、SQL、平面二进制或任何其他持久性方式,并允许您稍后将持久性层替换为其他东西。您可能最初开发应用程序以使用带有基本序列化程序的平面二进制文件来存储数据。稍后,出于性能原因,您可能会升级到 SQL ——并且这种更改只需要在一个位置——其工作——处理持久性,即关联的层/组件。否则,您必须遍历整个代码库来更改处理持久性的小部分。

于 2012-06-18T14:01:43.427 回答
1

只是说说你的例子,通过写 Person.Load(id) 你说 -通过查看他的标识符来加载这个对象- 你正在创建一个严格的工厂模式,只有当你知道他们的 ID 时你才能获取对象,稍后您会发现您需要根据某些搜索条件提取记录,并且您将添加更多工厂方法,而第二个解决方案已经为您提供了所需的所有自由。

第二种解决方案非常适合在运行时切换持久性逻辑,因为它与对象模型解耦,理论上您可以决定在客户端代码中使用哪种持久性引擎,而无需硬编码和触摸您的 OM,说您会需要更改MyContext的每个实例,您应该编写客户端代码以使其从某种工厂类或依赖注入中接收上下文。

作为一个例子,你可以有这个伪代码:

var person = onlineDbContext.Persons.Single(x=>x.Guid == myguid);

offlineDbContext.Persons.Add(person)
offlineDbContest.SaveOrUpdate();
于 2012-06-18T14:46:58.027 回答