Asp.net NHibernate折衷域对象

Asp.net NHibernate折衷域对象,asp.net,asp.net-mvc,nhibernate,oop,Asp.net,Asp.net Mvc,Nhibernate,Oop,我正在使用NHibernate作为我的ORM编写一个ASP.NETMVC应用程序。虽然我在设计上有点困难,但我还是希望得到一些意见 因此,我的问题是,我应该将我的业务/验证逻辑放在哪里(例如,电子邮件地址要求@,密码>=8个字符,等等) 那么,最有意义的是: 把它放在域对象本身上,可能放在属性设置器中 在我的域层之上引入一个服务层,并在其中为每个域对象提供验证器 维护两组域对象。一个用于NHibernate的哑集,另一个用于业务逻辑的智能集(以及它们之间的某种适应层) 我想我主要关心的是将所有验

我正在使用NHibernate作为我的ORM编写一个ASP.NETMVC应用程序。虽然我在设计上有点困难,但我还是希望得到一些意见

因此,我的问题是,我应该将我的业务/验证逻辑放在哪里(例如,电子邮件地址要求@,密码>=8个字符,等等)

那么,最有意义的是:

  • 把它放在域对象本身上,可能放在属性设置器中
  • 在我的域层之上引入一个服务层,并在其中为每个域对象提供验证器
  • 维护两组域对象。一个用于NHibernate的哑集,另一个用于业务逻辑的智能集(以及它们之间的某种适应层)
  • 我想我主要关心的是将所有验证放在NHibernate使用的域对象上。每次从数据库中取出对象时都进行不必要的验证检查,这似乎效率低下。说清楚一点,我认为这是一个真正的问题,因为这个应用程序的要求非常高(想想某些表中的数百万行)

    更新:
    我删除了一行关于NHibernate的错误信息。

    以澄清一些误解:

    a) NHib不要求您映射到属性。使用可以轻松地映射到字段。如果您喜欢使用属性或字段以外的内容,还可以定义自己的自定义策略

    b) 如果确实映射到属性,则getter和setter不需要是公共的。它们可以受到保护,甚至是保密的


    话虽如此,我完全同意当您从数据库检索实体时,域对象验证是没有意义的。因此,当用户尝试更新实体时,我会使用验证数据的服务。

    我当前的项目与您的项目完全相同。前端使用MVC,持久性使用NHibernate。目前,我的验证位于服务层(您的选项2)。但是,当我在编写代码时,我感觉我的代码并不像我希望的那样干净。比如说

    public class EntityService
    {
        public void SaveEntity(Entity entity)
        {
            if( entity.Propter1 == something )
            {
                throw new InvalidDataException();
            } 
            if( entity.Propter2 == somethingElse )
            {
                throw new InvalidDataException();
            }  
            ...
        }
    }
    

    这让我觉得EntityService是一个“上帝类”。它太了解实体类了,我不喜欢它。对我来说,让实体类来担心自己感觉好多了。但我也理解您对NHibernate性能问题的关注。因此,我的建议是在Setters中实现验证逻辑,并使用字段进行NHibernate映射

    感谢您的快速响应和澄清。好的,但是NHibernate不需要使用反射来访问字段(我真的不想公开它们),这也会很慢吗?它也使用反射来访问公共setter属性吗?它对属性和字段都使用反射。在构建会话工厂时,将尽可能多地缓存反射,以便在其运行时将性能损失降至最低。这种方法的缺点是在应用程序启动期间需要5-15秒来构建会话工厂。然而,这是以.NET框架为代价的。它与数据库查询无关。只要您使用NHibernate,您就必须准备好支付初始启动价格。我的建议将有助于通过删除验证逻辑来提高加载/存储性能。谢谢。我想我会将验证转移到域之上的服务层。这也有助于我的所有验证都可以在一个地点进行,因为有些验证需要了解其他域对象(例如,没有两个帐户可以共享同一个电子邮件地址)。哈,这是有意义的。如果您的验证需要对象间的知识,那么服务层的想法看起来更有吸引力。也许我也应该重新考虑一下重构代码的意图