请帮助您选择正确的n层Web应用程序架构

时间:2011-03-31 10:17:56

标签: c# asp.net n-tier-architecture

请帮助您选择在n层Web应用程序中使用实体的正确方法。 目前,我有以下汇编:

enter image description here

  1. 模型(自定义实体)描述了应用程序使用的类的字段。
  2. 验证是使用反射属性方法验证UI的数据完整性(检查所有层中的数据)。
  3. BusinessLogicLayer是一个业务外观,用于使用DataAccessLayer中的抽象数据提供程序的其他逻辑和缓存。
  4. DataAccessLayer使用LinqtoSql数据上下文和Linq查询覆盖abstarct数据提供程序。这就是让我觉得自己出错的重点...... 我的DataLayer在将数据发送到业务层之前,使用映射器将从DB检索到的数据映射(转换)到Model类(自定义实体)。它看起来像这样:

    internal static model.City ToModel(this City city)
    {
        if (city == null)
        {
            return null;
        }
    
        return new model.City
        {
            Id = city.CountryId,
            CountryId = city.CountryId,
            AddedDate = city.AddedDate,
            AddedBy = city.AddedBy,
            Title = city.Title
        };
    }
    
  5. 因此映射器将数据对象映射到描述模型。是正确和通用的方式与实体一起工作还是我必须使用数据对象作为实体(以获得时间)?我清楚了吗?

3 个答案:

答案 0 :(得分:2)

如果项目是POCO,您可以在项目中使用您的数据实体。否则我会像你一样创建单独的模型。但是请将它们保存在单独的程序集中(而不是在DataAccess项目中)

但我不会通过网络服务公开它们。

其他建议

imho人们过度使用图层。大多数应用程序不需要很多层。我现在的客户有一个类似你所有应用程序的架构。问题是只有数据访问层和表示层中有逻辑,所有其他层只从下层获取数据,对其进行转换,并将其发送到上面的层。

我做的第一件事是告诉他们废弃所有图层,而是使用这样的东西(需要一个IoC容器):

  • 核心(通过orm包含业务规则和数据访问)
  • 规范(分离的接口模式。包含服务接口和模型)
  • 用户界面(可能是网络服务,winforms,webapp)

适用于大多数应用程序。如果您发现 Core 增长并且变得太大,则可以将其拆分而不会影响任何用户界面。

您已经在使用ORM了,是否考虑过使用验证块(FluentValidation或DataAnnotations)进行验证?可以轻松验证所有图层中的模型。

答案 1 :(得分:1)

通常的做法是从服务边界(WCF服务等)发送DTO,但如果您在演示模型中直接使用“实体”,我认为没有任何好处。< / p>

至于您提供的代码段,为什么不使用AutoMappter?它有助于消除锅炉板映射代码的编写,如果您有一套惯例,那么就可以帮助您。

答案 2 :(得分:0)

现在摆脱模型,在删除它之前需要重构整个应用程序。我工作的最后一个项目使用了这个架构,维护DTO层和映射到数据库模型层是一个巨大的痛苦,并没有提供任何有用的好处。令人讨厌的主要问题之一是LinkToSql无法有效支持断开连接的数据模型。您无法通过创建具有与现有记录匹配的主键的新数据库实体来更新数据库表,然后将其粘贴到数据上下文中。您必须首先从数据库中检索实体,更新它然后提交更改。管理这会导致非常讨厌的更新方法,以将您的DTO中的所有属性映射到LinqtoSql类。它还打破了LinqToSql的整个延迟执行模型。甚至不要让我开始解决它导致的问题,这些问题是作为子DTO集合的父类的属性(例如,带有包含订单DTO集合的Orders属性的客户DTO),管理这些映射真的非常繁琐,我不得不进行一些广泛的优化,因为检索几百条记录最终导致LinqToSql进行200,000次数据库调用(不可否认,还有一些非常笨拙的代码,但你得到了图片)。

使用DTO的唯一正当理由是,如果您想拥有多个可插拔数据访问层,例如LinqToSql和NHibernate用于支持不同的DB服务器。这样,您可以在以后更换数据访问,而无需更改任何其他图层。如果你不需要这样做,那么为自己节省一个痛苦的世界,只需使用LinqToSql实体。