不使用数据集的N层架构(数据集听起来对性能不利)

Kas*_*hef 3 c# architecture performance ado.net webforms

我阅读了有关n层架构的书籍,文章,教程和所有类型的东西,我正在尝试应用着名的3层(DAL,BLL,PL),我刚进入游戏,实际上我已经阅读了很多关于将整个数据库加载到内存(数据集所做的)有多么糟糕的事情,特别是当我需要查看有关必须从5个表或其他东西检索的项目的详细信息时,它将是很多,我想要一个记录!并且我将需要许多记录的唯一情况它一次不会很多,它将检索非常简单的信息(id,name,address)这样的东西!

您认为在没有数据集的情况下找到另一种创建DAL和BLL的方法会更好吗?或数据集更好?如果数据集对性能不利等等,您是否有任何材料可以教我如何操作?

Dan*_*iel 5

所说的大部分都是可靠的建议.我同意,如果您正在考虑投入时间来构建N层应用程序,那么您应该考虑研究ORM解决方案.如果您使用的是.NET技术,那么EF4是构建DAL的一种非常好的方法.

您对DAL/BLL应该返回的内容的理解存在明显的混淆.DataSets现在在.NET 3和4中有点陈旧,但并不罕见.在构建DAL时,您应该阅读Repository设计模式.根据实现,您的存储库通常会返回一个通用的List<T> or IQueryable<T>.IQueryable是我的偏好,然而,有人认为它模糊了你的BLL和DAL之间的界限.

某些实现还要求每个聚合都有自己的存储库.(即CustomerRepository,EmployeeRepository)我发现最简单也是最好创建一个类型有约束的通用存储库.

例如:

Repository<TEntity> : IRepository<TEntity> where TEntity : ITrackable

要了解设计DAL的好方法,请查看nCommon.Tony Sneed有一篇关于在POCO中使用实体框架的精彩博客系列:http://blog.tonysneed.com/2010/02/19/trackable-dtos-taking-n-tier-a-step-further-with-ef4/

设计DAL和域层所花费的时间至关重要.

我的建议是主观的,不应该被认为是正确的或不正确的.我不知道您的申请的要求.如果您可以使用简单的数据集和sqldatareader更快地敲定一些代码,那么投资回报可能会更大.如果您正在寻求构建可维护的设计,请花费额外的时间阅读其他人建议的EF4和N层架构模式.


[编辑]

为了回应您在下面的评论,我想我可以分享一些我在学习架构时发现的宝贵资源.

首先要准备好进行无数小时的阅读和重读.利用您当前的知识和不断的实践,应用您学到的知识.最重要的事情是:你的设计永远不会是完美的,因为没有这样的东西,只是因为你应用一个模式并不一定能让它变得最好.

拥有自己的个人项目对于在OOP中取得进展是非常宝贵的.在马尔科姆·格拉德威尔(Malcolm Gladwell)的书"异常者"(Outliers)中,他认为在掌握一些东西之前,平均需要花费10,000小时的练习时间.所以继续编码和学习.:)

您可以选择的最好的书之一是Head First - Design Patterns.它被高度重视为OOD的一本非凡的入门书,并改变了你对代码的思考方式.我记得通过几章阅读并立即意识到,"哇!我一直在编写这样的代码,但从来不知道有它的名字!" 它帮助我意识到设计问题是多么熟悉; 他们有共同的解决方案,能够与其他开发人员进行沟通是多么重要.那本书会严重打击你的屁股(以一种好的方式).

但请注意,架构和设计书籍将为您提供设计适用的场景以及模式的实现.我花了一点时间才意识到可以有很多方法来实现这种模式......特别是在.NET中.当你开始阅读Martin Fowler,Robert C. Martin,Eric Evans,Dino Esposito的书时,你会看到.

有许多优秀的免费在线资源,如Microsoft的应用程序架构指南.一些最好的学习技巧方法就是阅读博客.

对于实体框架,很难击败Julia Lerman的编程EF4.为了澄清ORM的作用 - 它促进了与数据库的通信,并允许您"查询"它,就好像它是面向对象的.所以例如一些伪代码:

使用SqlDataReader,您通常会运行类似的查询

"SELECT * FROM Users WHERE Users.UserId = 1"

使用ORM,您实际上并没有编写SQL.ORM将数据库表映射到实际的类对象,从而允许您查询强类型对象.所以你会写下这样的东西:

User user = EFContext.Users.Where(u => u.UserId == 1).SingleOrDefault();

ORM负责将其转换为SQL并执行查询.此抽象还允许ORM通过提供程序可扩展性与多个数据库(MSSQL,Oracle,MySql)一起使用.

当您开始涉及分层体系结构时,您的Repository负责与ORM或数据库通信并将结果返回给BLL.例如,一个基本的例子看起来像:

using (var repository = new Repository<User>()) { User user = repository.Where(u => u.UserId == 1).SingleOrDefault(); }

这是ORM的一个非常基本的定义以及它是如何使用的.一旦你开始学习模式:如何识别它们,何时使用它们(不总是,因为它们可以使一些简单的事情复杂化)并重构你自己的代码,然后开始阅读域驱动设计.

希望这可以帮助.


[编辑2]

当然,让我澄清每层实际返回的内容.根据您的存储库实施和您的设计决策:

从您的基础架构层(ORM所在的层),您通常会返回通用List<T>或表示对象的IQueryable<T>where T.无论是实体对象还是POCO都取决于您.POCO只是一个代表你的数据的类,但它不仅仅是一堆吸气剂和二传手.它应至少包含验证.阅读贫血领域模型以及如何避免它们.

来自您的域层,其中包含业务逻辑,这取决于你想如何松耦合实现,你要么返回List<T>,BindingList<T>或您将使用的DTO的集合返回到您的演示文稿和服务层的映射技术.

DTO增加了另一系列复杂功能,但对某些情况至关重要.DTO是不可变对象.它们应该像这样构建:

[DataContract]
public sealed class UserSummary : IDto
{
[DataMember]
public String FirstName { get; private set; }

[DataMember]
public String LastName { get; private set; }

[DataMember]
public UserProfile Profile { get; private set; }

public UserSummary(String firstName, String lastName, UserProfile profile)
{
    FirstName = firstName;
    LastName = lastName;
    Profile = profile;
}

}
Run Code Online (Sandbox Code Playgroud)

他们 getter和setter的唯一袋.您的POCO应该能够轻松映射到它们,并且有一个很好的软件可以使这个过程变得简单:AutoMapper.它们不必在数据库或POCO对象中表示精确的表,但可以包含它们的几个部分,如上所示.

有一个问题.有时DTO的信息不足以返回您的服务或Web UI.您通常还需要返回验证结果,错误处理信息,可能需要布尔值来表示事务的结果.

这个对象没有确切的名称,但我继续将其称为响应传输对象,它组成了List<IDto>Microsoft企业库中的ValidationResults,以及我需要知道的任何其他内容.

这要消耗很多信息.在学习NLayer开发时,像每个层一样分解它.一次学习一件事,写下你脑子里的每一个问题.一定要找出答案.