【问题标题】:NHibernate compromising domain objectsNHibernate 破坏域对象
【发布时间】:2009-09-27 23:27:37
【问题描述】:

我正在编写一个使用 NHibernate 作为我的 ORM 的 ASP.NET MVC 应用程序。不过,我在设计上有点挣扎,希望得到一些意见。

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

所以,这是最有意义的:

  1. 将它放在域对象本身上,可能在属性设置器中?
  2. 在我的域层之上引入一个服务层,并为其中的每个域对象设置验证器?
  3. 维护两组域对象。一组用于 NHibernate,另一组用于业务逻辑(以及它们之间的某种适配层)。

我想我主要关心的是将所有验证放在 NHibernate 使用的域对象上。每次我将对象从数据库中拉出时,进行不必要的验证检查似乎效率低下。需要明确的是,我认为这是一个真正的问题,因为这个应用程序要求很高(想想某些表中的数百万行)。

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

【问题讨论】:

    标签: asp.net asp.net-mvc nhibernate oop


    【解决方案1】:

    澄清几个误解:

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

    b) 如果您确实映射到属性,getter 和 setter 需要公开。它们可以受到保护甚至是私有的。

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

    【讨论】:

    • 感谢您的快速回复和澄清。
    【解决方案2】:

    我目前的项目和你的完全一样。前端使用 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是一个“神级”。它对 Entity 类了解太多,我不喜欢它。对我来说,让实体类自己担心会好得多。但我也理解您对 NHibernate 性能问题的担忧。因此,我的建议是在 Setters 中实现验证逻辑并使用字段进行 NHibernate 映射。

    【讨论】:

    • 好的,但是 NHibernate 不需要使用反射来访问字段(我真的不想公开它们),这也会很慢?是否也使用反射来访问公共 setter 属性?
    • 它对属性和字段都使用了反射。在构建会话工厂时尽可能多地缓存反射,以最大程度地减少运行后的性能损失。这种方法的缺点是在应用程序启动期间需要 5-15 秒来构建会话工厂。
    • 正如 Paco 所说,使用反射很慢。然而,这是以 .NET 框架为代价的。它与数据库查询无关。只要您使用 NHibernate,您就必须准备好支付初始启动价格。我的建议将有助于通过删除验证逻辑来​​提高加载/存储性能。
    • 谢谢魏。我想我将把验证移到域之上的服务层。这也有助于我的所有验证都可以在一个地方进行,因为某些验证需要了解其他域对象(例如,没有两个帐户可以共享同一个电子邮件地址)。
    • 哈,有道理。如果您的验证需要对象间知识,那么服务层的想法看起来更有吸引力。也许我也应该重新考虑我重构代码的意图。 :)
    猜你喜欢
    • 2010-12-25
    • 1970-01-01
    • 2015-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    相关资源
    最近更新 更多