65.9K
CodeProject 正在变化。 阅读更多。
Home

自动生成全面的 C# 数据访问层

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (29投票s)

2006年10月26日

9分钟阅读

viewsIcon

185359

一个简单但强大的 GUI 对象关系映射器,可生成 C# 2.0 代码来处理您所有的对象关系持久化。

目录

引言

OR.NET 是一个开源的对象关系映射器/代码生成器,适用于 SQL Server 和 .NET 2.0 框架。我最近发布了一篇关于 OR.NET 的文章,在对项目进行了重大更新后,我觉得这篇更全面的文章会更合适。

简而言之,OR.NET 通过一个简单的 GUI 收集所有必需的对象关系信息,然后完全用 C# 2.0 生成一个全面的数据访问层。它支持可空类型、泛型和非泛型集合、外键和映射表关系、SQL Server 标识列、事务管理等等。

上面的下载链接将允许您免费下载完整的源代码、可执行文件和全面的用户手册。我不会直接在这里发布代码,因为在多个位置维护这个项目会很不方便。另外,OR.NET 的主页可以在这里找到: O/R Mapper

准备工作

万一有人只读了这篇文章的一小部分然后下载了应用程序,我想说明的是,在生成 DAL 代码后,您必须在将生成的代码引入的任何 .NET 项目中添加对 System.Transactions 库的引用。这显然是 OR.NET 提供的分布式事务能力所必需的。

背景

目前,在对象关系映射社区中,关于代码生成和内部 DAL 哪个更优存在激烈的争论。我既不打算在此解决这场争论,甚至不打算认真参与其中。我只想说,我创建 OR.NET 作为代码生成器,是因为我个人希望在项目中拥有绝对的控制权,这样,如果出现特定需求,我可以直接在 SQL 层面进行有针对性的修改。通过应用程序文档来学习如何通过内部 DAL 实现相同目的的方式在我看来不太可取。

本文的其余部分将对使用 OR.NET 的 GUI 和生成的代码分别提供一个很好的概述。我写这篇文章的目的是提供一个关于如何使用该程序的扎实描述,然后是关于如何使用生成的代码。它不会深入探讨底层源代码、DAL 的内部细节或 GUI 的一些更高级功能,因为我觉得在这里放置如此多的信息会让文章难以阅读且不吸引人。对这些信息感兴趣的人可以免费下载源代码和用户手册。

使用 GUI

本节将包含对 GUI 功能的基本描述。

开始新项目。

文件 -> 新建项目菜单项显然会启动一个新项目。用户需要输入 Microsoft SQL Server 数据库的连接信息(也可以添加更多数据库)。这些信息通过一个简单的表单(未显示)进行记录。一旦至少输入了一个数据库,您就可以开始输入关于您的业务对象及其与数据库关系的详细信息了。

输入新类

下面的截图显示了用于输入新类的表单。正如您所见,顶部部分包含所有标准的类信息:类名和命名空间。中间部分是您指定类所基于的数据库和表。

标识键

标识键是通过数据库列创建的属性,这些属性组合起来可以唯一地标识一个对象。这些在上面显示的新类表单的底部部分进行指定。大多数对象将只有一个标识键,基于表的 PRIMARY KEY,但 OR.NET 可以轻松支持具有复合键的表。

SQL Server 标识列

标有“DBMS 管理键”的复选框允许用户指定基于 SQL Server 标识列(由 DBMS 维护的唯一列)的标识键。在这种情况下,生成的代码在创建新对象时不会提示输入此字段的值,而是将其留给 DBMS 计算值。

持久化属性

持久化属性代表那些基于单个数据库列的类属性。下面显示的表单用于指定单个类的所有持久化属性。正如您所看到的,表单默认会为表中的所有列创建属性,并带有默认名称和数据类型 - 所有这些都可以更改。

可空持久化属性

(上图)中的持久化属性表单的最后一列指定了相应的数据库字段是否可为空。如果设置了此选项,则底层属性将被声明为 .NET 2.0 的可空类型。除此之外,每次生成的 DAL 需要对此属性执行任何操作时,它都会首先检查 null 值。由于所有这些开销,建议对于您知道将始终包含实际值的可空列,保留默认的非可空设置。

复合关系

下图显示了用于收集单个复合对象信息的表单。用于对象集合的表单是相同的,除了空白区域包含有关返回的集合类型的信息(支持所有泛型和非泛型集合)。

复合对象依赖

OR.NET 允许您通过两种方式在持久化类之间创建复合关系:通过一个表到另一个表的外键,或者通过第三个映射表。标有“连接到 XXX 表”的下拉列表指定了使用哪种选项。

外键依赖

如果选择“直接”,则会出现以下表单,要求您指定两个类之间的外键关系。

如果选择“通过映射表”,则会出现以下表单,要求您指定两个类之间的关系以及映射表。

一旦所有信息输入完毕,您的主项目页面应该看起来像页面顶部的图像。

生成代码

要生成 DAL 代码,请从“项目”菜单中选择“生成代码”,告诉 OR.NET 代码存放位置,您就完成了。现在您可以开始使用您的持久化对象,而无需处理任何 SQL。

使用生成的代码

假设我创建了以下 Book 类。引用的每个对象都代表另一个持久化类,出于简洁起见,我已省略了它们。此外,我将代码进行了一些截断,并删除了属性的 get / set 部分(它们没什么特别之处)。

    public partial class Book {
        #region ClassKeys
        public string BookISBN;
        #endregion

        #region PersistentAttributes
        public string title;
        public string subtitle;
        public int publisher;
        #endregion

        #region EmbeddedObjects
        public ThesisDemo.Publisher BookPublisher;
        #endregion

        #region PersistentCollections
        public List<ThesisDemo.Author> Authors;
        private List<ThesisDemo.Genre> Genres;
        #endregion
    }

介绍 Assembler 类

对于生成的每个持久化类,都会创建一个相应的 Assembler 类。对于上面讨论的书籍类,它将被称为 BookAssembler。这个 Assembler 作为数据库和持久化类之间的桥梁。它负责您所有的读取、更新、插入和删除操作。

用户手册详细介绍了 Assembler 类的内部工作原理,但简而言之,它是对 Clifton Nock 的《Data Access Patterns》(Addison-Wesley,2003)中的 Domain Object Assembler 类的扩展。

从 DBMS 读取对象

为了从 DBMS 读取一本书,您首先必须实例化一个 BookAssembler,然后调用 ReadSingle 方法,并将所有标识键作为参数传递,在本例中只有一个 ISBN。如用户手册所述,ReadSingle(以及 ReadCollection)方法还有一个接受 Criteria 对象的重载。Criteria 对象允许用户以面向对象的方式指定在从 DBMS 读取对象或对象集合时必须满足的某些条件。

BookAssembler ba = new BookAssembler(); 
Book b = ba.ReadSingle("0-7645-7135-4");

修改对象

从这里开始,对象可以像其他任何对象一样进行修改。也许,我们想向 Authors 集合添加一个作者并设置其标题。

b.title = "Professional .NET Framework 2.0" 
b.Authors.Add(new Author("Joe Duffy"));

持久化对象

为了保存我们对对象所做的更改或插入新对象,您将调用 BookAssembler 中的 MakePersistent 方法。是更新对象还是插入对象,是基于 DAL 插入到类中的 IsNew 属性的值来决定的。此属性存在于一个单独的文件中(由 partial 关键字实现),并由 DAL 完全管理。

MakePersistent 的第一个参数是要持久化的对象。第二个参数是一个自定义的 CascadeType 枚举,指定如何持久化复合对象。如果指定 CascadeType.None,则不会持久化复合对象。如果指定 CascadeType.MappingTablesOnly,则只会更新用于持久化多对多集合的映射表(但不会更新集合中的对象)。最后,如果指定 CascadeType.Complete,则会持久化所有内容。对于不包含任何复合对象的类,此参数将被省略在生成的 MakePersistent 方法之外。

ba.MakePersistent(b, CascadeType.Complete);

MakePersistent 还定义了其他重载,允许您指定所使用的事务管理类型。这些重载在此未讨论,但与此处未讨论的任何其他功能一样,都在用户手册中涵盖。

删除对象

为了从数据库中删除一个对象,Assembler 指定了一个 Delete 方法,该方法按预期工作,并包含与 MakePersistent 相同的所有重载,但有一个例外。这里,级联参数是布尔值,指定是否删除底层复合对象。无论指定什么值,用于复合对象的所有映射表都将更新以反映父对象的移除。

摘要

OR.NET 是一个功能强大的对象关系映射器和代码生成器,适用于 .NET 2.0 框架。用户手册将提供关于生成代码所有方面的详尽细节,而这里只讨论了一小部分。

我一直在寻找反馈,所以如果您有任何意见,请随时提出。

感谢阅读!

© . All rights reserved.