面向未来的 DAL
Posted
技术标签:
【中文标题】面向未来的 DAL【英文标题】:Future Proof DALs 【发布时间】:2011-06-11 09:41:06 【问题描述】:我们正处于一个非常长的开发项目的开始,其中包含几个子项目。基本上每个子项目都需要几个月的时间来开发。代码本身将被拆分为多个 C# 项目,但物理数据库将由所有项目共享。
问题在于可维护性。如果我们向表中添加列,或将表拆分为两个较小的表,则必须返回并修改 C# DAL 以支持这些更改。这是不可接受的,因为我们将不断调整数据库以符合整个公司的需求,而不仅仅是单个程序的需求。不断更改旧代码将是一项永无止境的任务。
我们的 DB 人员提出了不同的看法。我们通过存储过程完成所有的 CRUD,并跨多个表使用 Linq 来执行我们的 SELECT 语句。然后,如果我们在几年后重新构建数据库,我们可以简单地提供相同的存储过程和视图,而不必修改旧代码。
我们的问题是,对于这样的事情应该使用什么 ORM? EF 似乎有点矫枉过正(也许不是)。像 SubSonic 这样的 T4 模板是否允许更简单(也许更快)的 DAL?
或者也许有人知道如何让整个过程不那么痛苦?我们宁愿不向我们的应用程序添加另一层,但我们也不想在每次更改数据库时返回并修改代码。
编辑 1: 所以当我说“我真的不想添加更多图层”时。这主要是因为我们已经有好几层了。我们有 Silverlight 视图、视图模型、BLL 对象(通过 CSLA),然后是 DAL,最后是 SQL 表。
【问题讨论】:
因此,通过尝试使用一个 Schema 来为所有用户提供服务,您基本上会得到最糟糕的模型。我总是想知道人们如何在不接触访问它的应用程序的情况下更改数据库。这似乎超现实。 通过数据库进行集成在 70 年代后期过时了。除非您使用的是像 Gemstone 这样的 OODB。 我是唯一一个认为这个问题会得到很多观点和答案但没有真正有用的人吗? @flq - 想象一个工资计划。假设工资系统真的只关心个人的工资,以及他们工作的小时数。稍后,我们添加了一个计费系统,该系统根据员工的账单费率向客户计费。该账单费率与工资单无关,所以我为什么要返回并编辑可能已有多年历史的代码,只需添加报告程序所需的字段。 你为什么不创建一个服务(例如 WCF/OData 等),它也充当 DAL 并存在于它自己的服务器上。该服务使用 与数据库对话。然后所有项目都与 WCF 服务通信。如果数据库发生变化,只有 WCF 服务需要 - 服务合同保持不变。 【参考方案1】:根据http://ormeter.net/的性能信息,我已经开始使用BLToolkit
您可以在简单的类文件中定义您的模型,添加一些应用了属性的方法,然后您就有了一个 DAL。将表一分为二,您可以在创建新的类文件时维护原始类文件以支持拆分表。只需确保您创建了一个测试项目,该项目适用于每种方法,以确保它们都适用于每个版本
类
public class DirectoryListing
[PrimaryKey, Identity]
public Int64 Id get; set;
public Int64? OldId get; set;
public Int32 CategoryId get; set;
[Nullable]
public String CompanyName get; set;
一般选择或表值函数:
[SqlQuery("SELECT * FROM Ajax_CategorySearch(@SearchString, @ResultCount)")]
[Cache(MaxCacheTime = 10, IsWeak = false)]
public abstract List<String> AjaxCategorySearch(String @SearchString, Int32 @ResultCount = 10);
或者使用存储过程:
[ActionName("SelectById")]
public abstract Model.DirectoryListing SelectById(Int64 @Id);
这将调用 SP DirectoryListing_SelectById
哦,用更经典的方式做事也很容易
using (BIFDbManager db = new BIFDbManager())
var output = db.SetCommand(
"SQL GOES HERE",
db.Parameter("@Id", 1))
.ExecuteList<DAL.Model.DirectoryListing>();
totalrecords = output.Count();
return output;
最后一个难题是数据库管理器,它还支持 LINQ。
public class BIFDbManager : DbManager
public BIFDbManager() : base("Connection string name")
public Table<DirectoryListing> DirectoryListings get return GetTable<DirectoryListing>();
【讨论】:
所以你建议我手动创建我的 DAL 对象? 好吧,我这样做只是为了保持控制,但你不必这样做。 bltoolkit.net/Doc.T4Templates.ashx?HL=t4【参考方案2】:C# DAL... not just the needs of a single program
。 C# DAL 作为一个单独的程序集的全部意义在于它可以在任何类型的 .NET 应用程序中重用。您将遇到的主要问题是,如果数据库发生更改,则 DAL 必须更改(一次),然后必须使用新 DAL 重新部署所有依赖于 DAL 的应用程序。您还有一个问题,即 DAL 不能被非 .NET 应用程序使用。
好的,那么如何集中 DAL 以便不必为每个应用程序重新部署它?想想 SOA。您可以构建一个 WCF 服务来包含 DAL(可能还有 BLL)。您的所有应用程序(如果您使用 Web 服务,甚至那些不是 .NET 的应用程序)都可以使用此服务。当数据库更改时,您更新 WCF 服务并部署一次。只要确保您没有进行任何重大更改!如果您需要添加/更改功能,请创建一个 MyMethod2。
注意:当您听到 n-tier 时,通常是 指三层,其中每一层 是单独的软件,通常在 单独的服务器:展示(UI), 应用程序(您的 BLL/DAL)、数据(您的 SQL 数据库)。这种架构有其优点。
We'd rather not add another layer to our application
。好的,所以在您的情况下,三层可能不是最好的方法。
neither do we want to go back and modify code everytime we make a db change
那么你的DBA人建议是唯一的方法。
但是,请考虑一下:更改存储过程与修改代码相同吗?基本上是一样的。 SQL 存储过程通常不受版本控制或测试,但它们应该是。 SQL 没有 .NET 等语言的丰富性。 WCF 可以在 Web 场中轻松扩展。一旦考虑到这些和其他原因,可能值得采用三层/SOA 方法。
这实际上取决于您的项目规模、员工技能、未来发展等,而这只有您可以确定。
【讨论】:
【参考方案3】:没有数据库你能工作多久?如果有问题,请晚一点介绍。是的,这可能意味着您添加了一个图层。
【讨论】:
以上是关于面向未来的 DAL的主要内容,如果未能解决你的问题,请参考以下文章