.NET ORM需要虚拟,而不能处理密封?

Dom*_*nic 13 .net nhibernate orm entity-framework class-design

我刚刚开始使用.NET ORM,我还没有在Entity Framework和NHibernate之间做出决定.但在这两种情况下,我遇到了一个问题,因为他们似乎希望我以各种方式破坏我的域模型的完整性,特别是在C#对象设计的更精细点上.这是关于这个问题的几个问题之一.


一个原因virtual不是C#中方法的默认值.我的域模型中的对象没有准备好对子类的行为做出承诺,除非在非常具体的情况下我将它们标记为这样.换句话说,对于我的域对象上的极少数方法,为未指定的新功能添加一个钩子是合适的.

然而NHibernate希望我做出一切virtual,Entity Framework希望我做出所有实体引用virtual.我意识到为什么他们需要它(创建代理对象),并且我意识到它实际上是继承的合法用法virtual- 它们实际上为了添加新功能挂钩我的属性.但它让我觉得我必须使用完全与持久性相关的东西来注释我的域模型类,并且完全没有表达它们与实现者和消费者的实际契约.

作为一个较小的问题,我意识到我可能无法做任何事情,通常是表达sealed 因为所有通常的原因来注释我的课程.然而,这有点不那么光滑,因为为了持久性而从我的域对象中省略注释似乎不如添加注释.


令人沮丧的是,经过几年阅读像Effective C#这样的书或像Eric Lippert那样的博客,它们提供了关于如何设计富有表现力和防弹的C#对象的建议,使用ORM的需要让我把大量的知识从窗口.我希望这里有人可以指出我错在哪里,要么掌握他们的能力,要么是我对域建模和ORM角色的思考.

Bev*_*van 19

它不仅仅是.NET ORM - 同样的约束也适用于Java ORM.

虽然在Java中,除非您明确声明,否则一切都是虚拟的,因此满足ORM的需要与您所发现的情况非常相似sealed:

为了持久性而省略我的域对象中的注释似乎不如添加注释.

它归结为:持久性无知是一个有价值的目标,但它不是100%实现的目标,除非你也愿意忽略内存负载性能等细微细节.

如果内存负载性能无关紧要,请停止使用代理并要求所有对象在它们保持水分后立即完全填充 - NHibernate可以通过配置执行此操作.副作用是所有相关对象将一次加载,因此您最终将大部分数据库加载到内存中.该应用程序将需要大量内存并花费大量时间来启动 - 但它会工作.

持久性是一种渗透性的抽象 - 虽然你可以将其中的大部分隐藏在幕后,但总会有元素泄漏到应用程序的其他区域.


Eri*_*sch 8

如何轻轻地放这个......对不起,我不能.克服它.

我100%同意你,但使用框架总是意味着妥协.不想妥协?自己构建它.这就是它的全部内容.

为了减少对抗性,有一个解决你的问题的方法,那就是使用像automapper这样的东西在你的漏洞持久性子系统和你的应用程序的其余部分之间进行转换.基本上,您保持您的域模型干净整洁,并按照您喜欢的方式进行设计,然后使用转换层在它与您讨厌,丑陋的ORM之间进行映射.

但是,这真的是很多工作.对于少量的纯度,你放弃了你,省去了很多努力.


Ste*_*ven 7

有一个原因虚拟不是C#中方法的默认值[链接到Anders Hejlsberg的采访].

Hejlsberg实际上是在谈论框架API设计.他没有谈论业务线应用程序.因此,他的规则在LOB应用程序中应用较少.由于您使用的是O/RM,因此您可能正在编写LOB应用程序.

由于所有常见的原因[链接到Eric Lippert的博客],通常表达密封注释我的课程.

您正在引用Eric Lippert的一篇文章,他在C#编译器团队的工作环境中撰写了该文章.一般框架设计指南实际上包含相反的指导原则:

没有充分的理由不要密封课程.[第6.3段]

换句话说,Eric Lippert所说的并不是常见的规则.

就个人而言,当我编写LOB应用程序时,我实际上会密封我的类并尽可能地编写非虚方法.但是,这与在后续版本中引入重大更改的更改无关,因为这几乎只是一个框架设计问题.

不,我这样做是因为它让我更容易对我的代码做出假设.换句话说:它使我的代码更易于维护.

但是,当我需要执行此操作时,我完全没有启动类或虚拟化方法的问题.我这样做的主要原因是允许我的代码可测试.

显然你也需要这种灵活性,因为你正在编写一个LOB应用程序,所以要务实并记住:

无论如何,它们更像是指南

  • 这是一个非常有用的澄清; 我现在看到,我从我链接的博客文章中删除了正确的课程,同时误解了他们的背景.正如您所说,实际上它是为了更容易做出假设从而维护代码.但是,根据需要进行开封和虚拟化并不是那么糟糕,这一点非常有意义. (2认同)