.NET ORMs、不可变值对象、结构、默认构造函数和只读属性

.NET ORMs、不可变值对象、结构、默认构造函数和只读属性,.net,orm,class-design,immutability,value-type,.net,Orm,Class Design,Immutability,Value Type,我刚刚开始使用.NETORMS,甚至还没有决定使用实体框架和NHibernate。但在这两种情况下,我都遇到了一个问题,因为他们似乎希望我以各种方式损害域模型的完整性,特别是在C对象设计的更精细点上。这是关于这个问题的几个问题之一 我非常习惯于使用如下模式在适当的属性上强制执行不变性: public class Foo { private readonly string bar; public string Bar { return this.bar; } public

我刚刚开始使用.NETORMS,甚至还没有决定使用实体框架和NHibernate。但在这两种情况下,我都遇到了一个问题,因为他们似乎希望我以各种方式损害域模型的完整性,特别是在C对象设计的更精细点上。这是关于这个问题的几个问题之一

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

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

    public Foo(string bar)
    {
        this.bar = bar;
    }
}
NHibernate或实体框架似乎不支持这一点。他们需要默认构造函数和公共设置器;看起来甚至私有setter和默认构造函数有时也能工作?因为ORMs可以使用反射

我想我可以通过使用私有setter和私有默认构造函数来解决这些问题。至少这样,公共API不会受到损害。只是我正在修改我所有类的实现,以添加未使用的私有构造函数,并且必须相信未来的Domenic,他理解我的setters上的private,这意味着除了在构造函数中,不要调用我。持久层正在泄漏到我的域对象设计中

它似乎也没有必要——为什么ORM不知道使用非默认构造函数呢?也许他们能做到,但我只是没有找到合适的博客来解释如何做到

最后,在某些情况下,我的不可变值对象实际上适合不可变值类型,即结构。我猜想这是可能的,因为在数据库中,结构的字段将显示在父实体存储的同一行中。你能证实/否认吗?看起来很有希望,因为它给出了一个肯定的答案,但实际上特定于所讨论的值类型的代码数量令人震惊


令人沮丧的是,在阅读了几年诸如Efficient C之类的书籍或Eric Lippert之类的博客(这些书籍为如何设计富有表现力和防弹性的C对象提供了很好的建议)之后,使用ORMs的需求让我把这些知识抛到了窗外。我希望在座的人能指出我的错误,无论是在我对他们的能力的理解上,还是在我对领域建模和ORM角色的思考上。

正如评论所指出的,当/如果你采用ORM时,你必须做出一些妥协。在我看来,需要记住的是,生产率的提高远远超过了这些妥协的成本


我确实想向你们指出,因为你们是EF的新手,你们可以生成EF实体和上下文。我认为,如果你认真对待这个问题,你可以解决大部分你不喜欢的事情。

使用了许多ORM之后,我感到很痛苦,使用接口、抽象和不可变对象无法与大多数ORM正常工作。正是出于这个原因和其他原因,我在大约8年前写了自己的,我用自己的ORM发现了一些问题,并找到了解决这些问题的方法。我会看看Micro ORM,看看你能找到什么,有很多这样的产品,有丰富的功能集,而且很多产品的行李更少

我在我的手机上添加了一些新功能来处理我的一些烦恼。例如,能够返回接口或其他抽象类型的集合,以及不可变类型

    string sql = "Select * from simpleEntities";
    ISqlQuery query = _factory.CreateSqlQuery(sql, nameof(AbstractFactoryTests.ReadImmutableEntityItems));
    IList<IImmutableEntity> items = loader.ObtainItemsImmutable<IImmutableEntity>(query);
或:


你至少有三个问题可以归结为我不喜欢ORMs,因为它们破坏了我的设计。ORM是解决特定问题的工具。如果你不喜欢它们,为什么要使用它们?使用ADO.NET编写自己的数据访问层。在输入样板代码几个月后,您可能会意识到需要权衡。几年前我也做过类似的事情;我不会再回去了。是的,这些都是我开始研究ORMs时提出的相关问题。但我更愿意将它们归类为帮助我理解ORM问题中的妥协。我承诺使用ORM,因为正如您所说,ADO.NET中的数据访问是疯狂的。并不是我不喜欢它们,而是我仍然在学习它们,并试图帮助自己树立正确的心态。例如,如果我在阅读EF与NHibernate的比较时,脑海中的问题会减少我的领域模型中的妥协?,这可能比在这种比较中考虑什么样的折衷通常是必要的,而不是根据特性、成熟度、能力等来比较这两个框架的效率要低。
    IList<ISqlQuery> queries = new List<ISqlQuery>();

    // Note, no register types needed here because of returnType parameter

    ISqlQuery s1 = _factory.CreateSqlQuery("Select * from Employee where EmployeeType=1", "LoadAbstract.ParallelLoadItems1", typeof(Employee));
    queries.Add(s1);
    ISqlQuery s2 = _factory.CreateSqlQuery("Select * from Employee where EmployeeType=2", "LoadAbstract.ParallelLoadItems2", typeof(Manager));
    queries.Add(s2);
    ISqlQuery s3 = _factory.CreateSqlQuery("Select * from Employee where EmployeeType=3", "LoadAbstract.ParallelLoadItems3", typeof(DistrictManager));
    queries.Add(s3);

     IList<IEmployee> data = loader.ParallelLoadAbstractItems<IEmployee>(_factory, queries);