我刚开始使用.NET ORM,以至于我什至还没有决定在Entity Framework和NHibernate之间进行选择。但是在这两种情况下,我都遇到了一个问题,即他们似乎希望我以各种方式损害域模型的完整性,尤其是在C#对象设计的某些方面。这是关于这个问题的几个问题之一。

我非常习惯使用如下所示的模式在适当的属性上强制不变性:

public class Foo
{
    private readonly string bar;
    public string Bar { return this.bar; }

    public Foo(string bar)
    {
        this.bar = bar;
    }
}

NHibernate或Entity Framework似乎不支持此功能。他们想要默认的构造函数和public setter;由于ORM可以使用反射,因此private设置程序(和默认构造函数)似乎也起作用(有时?)。

我想我可以通过使用private setter 和private默认构造函数来解决这些问题。至少公共(public)API不会受到损害。仅仅是我正在修改我所有类的实现以添加未使用的private构造函数,并且不得不信任future-Domenic,他了解我的setter上的private确实意味着“除了在构造函数中,不要给我打电话”。持久层正在泄漏到我的域对象设计中。

这似乎也没有必要-为什么ORM不知道使用非默认构造函数?也许他们有能力,但我只是没有找到正确的博客文章来解释如何做。

最后,在某些情况下,我的不可变值对象实际上适合(不可变)值类型,即struct。我的猜测是有可能的,因为在数据库中,结构的字段将显示在存储父实体的同一行中。您可以确认/拒绝吗? This blog post看起来很有希望,因为它给出了肯定的答案,但是代码的数量(实际上是特定于所讨论的值类型的)使思维困惑。

令人沮丧的是,在几年后阅读了诸如Effective C#之类的书籍或诸如Eric Lippert之类的博客之后,这些博客就如何设计富有表现力和防弹的C#对象提供了很好的建议,使用ORM的需要使我从中学到了很多知识。 window 。我希望这里的人可以指出我的错,无论是在掌握他们的能力方面,还是在我对域建模和ORM角色的思考中。

最佳答案

正如评论所指出的那样,当您采用ORM时,您将不得不做出一些让步。我认为要记住的是,生产力的提高远远超过了这些折衷的“成本”。

我确实想向您指出(因为您是EF的新手),您可以customize the T4 templates生成EF实体和上下文。我认为,如果您尝试使用此功能,则可以消除大部分您不喜欢的东西。

10-01 19:56
查看更多