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

对象持久化:通往 N 层涅槃之路

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2006年12月1日

7分钟阅读

viewsIcon

25182

使用敏捷托管数据库框架,感受编程天堂般的体验。

这是我们赞助商 CodeProject 的产品展示评测。这些评测旨在为您提供我们认为对开发人员有用且有价值的产品和服务信息。

引言

Crainiate Objecto 旨在让您能够轻松创建敏捷的 N 层数据类,使用 Microsoft .NET Framework 2.0 或更高版本,这些类可重用、可继承且可扩展。在本文中,我们将探讨对象持久化如何让您专注于编写灵活的敏捷业务对象框架,并停止为数据库访问和部署而烦恼。

什么是对象持久化?

对象持久化可以理解为对象到关系数据库的智能序列化和检索。通过持久化,类的实例,例如 Person 或 Customer,可以无缝地保存到底层数据库表中,并在未来的任何时候检索回来——作为具有相同属性值的类的另一个实例。要了解对象持久化强大功能的最简单方法是创建并使用一个可持久化的类。

using System;
using Crainiate.Data.Persistence;

public class Person: Table
{
    private int _Id;
    private string _Name;

    [PrimaryKey(1, 1)]
    public int Id
    {
        get {return _Id;}
        set {_Id = value;}
    }

    [Column]
    public string Name
    {
        get {return _Name;}
        set {_Name = value;}
    }
}

在上面的示例中,我们创建了一个新的 Person 类来保存一些基本详细信息,包含标准的 IdName 属性。有两个因素使该类可持久化。首先,属性被 PrimaryKeyColumn 属性修饰,这使得底层数据库能够准确知道如何将该类的实例存储在表中。其次,该类继承自 Table 基类。当查看第二个代码示例时,Person 类从 Table 继承的好处将变得清晰。

    //Insert a person
    Person person = new Person();
    person.Name = "John Smith";
    person.Insert();

    //Retrieve a person with a known Id
    person.Id = 3;
    person.Select();

Table 类为我们提供了类似 SQL 的方法,让我们了解可以对对象执行哪些操作。当我们调用 InsertUpdate 方法时,底层数据提供者会将对象中的属性值保存到数据库中的表中。Select 方法根据标记为 PrimaryKeyId 属性的值来填充对象的属性。在上面的示例中,每次插入 Person 类时,都会自动为其创建新的主键。

这如何工作?Objecto 使用一项名为托管数据库部署的新技术。当您部署包含一个或多个持久化类的程序集时,数据提供者会连接到选定的目标数据库,并检查底层架构,以添加或更改任何数据库表或字段,从而能够安全地存储程序集最新版本的实例——且不会丢失任何数据。当调用 SelectInsertUpdate 方法时,提供者会决定是创建新的存储过程还是使用现有的存储过程来处理请求。

为什么对象持久化如此强大?

对象持久化结合了关系数据库的强大功能和可扩展性,以及完全面向对象的数据设计的灵活性。您的类定义了数据的结构,并封装了业务逻辑——数据提供者会自动管理底层数据库的结构和访问。这使您可以专注于实现业务规则,而不是编写使应用程序在解决方案的不同层之间工作的代码。

继承的常规规则适用于持久化对象。在创建派生类时,数据会无缝地链接在一起,填充单个对象实例。这通过使用通用类来促进业务逻辑的重用,更专业的类继承基础功能——而无需担心更改底层数据库。Objecto 将创建一个托管的规范化数据库设计,包括索引和约束。对您的对象接口的更改将自动部署到数据库,使您的应用程序易于更改和增强。

以下示例演示了从 Person 派生的 Customer 类的创建。

    public class Customer: Person
    {
        private float _CreditLimit;

        [Column]
        public float CreditLimit
        {
            get {return _CreditLimit;}
            set {_CreditLimit = value;}
        }
    }

Customer 类继承了现有的 Person 结构和功能,并且可以在应用程序中使用 Person 类的地方使用,并且额外提供了 CreditLimit 以便在新功能需要时使用。当派生类被插入、更新或选择时,底层数据提供者将自动处理底层存储过程以修改相应的数据结构。您无需访问源代码即可继承持久化对象——这样,第三方就可以增强您的数据驱动应用程序,而无需理解底层数据库结构。

查询持久化类:对象重用与集合论的结合

关系数据库旨在提供一组结果,通常通过将两个独立表中的常见信息合并到一个结果集中。Objecto 包含用于处理持久化对象集合的类。继续使用类似 SQL 的命名约定,泛型 Query 类充当数据库查询的面向对象的接口。

要返回数据库中所有 CreditLimit 大于 500 的 Customer 实例,我们创建一个新的 Customer Query 对象。

    Query<Customer> query = new Query<Customer>(); 
    PropertyInfo prop = typeof(Customer).GetProperty("CreditLimit");
    Condition condition = new Condition(prop, 500);
    query.Where.Add(condition);

    //Set the database context and execute the query
    query.Context = Context; 
    query.Execute();

    //Loop through the customer results
    foreach (Customer customer in query.Results)
    {
        //Process customer here
    }

Where 集合包含条件信息,决定了在调用 Execute 方法时返回哪些对象实例。要查看结果,只需遍历 Results 属性集合即可。无需数据集或 XML 映射文件,Results 属性将返回 Customer 对象实例的集合。

如果不需要整个对象实例的所有属性怎么办?泛型 View 类可用于创建仅包含完整对象属性子集的其他类。在高吞吐量环境中,可以使用 DataReader 直接处理查询结果,而无需为每个记录创建对象。

Query 类足够强大,可以与任何其他查询使用 Join 方法进行连接。在下一个代码示例中,将 CustomerAddress 查询与 Address 查询连接起来,并且只返回两个查询共有的实例。

    Query<CustomerAddress> query1 = new Query<CustomerAddress>();
    Query<Address> query2 = new Query<Address>(); 

    PropertyInfo propFrom = typeof(CustomerAddress).GetProperty("AddressId");
    PropertyInfo propTo = typeof(Address).GetProperty("Id");

    query1.Join(query2, propFrom, propTo);

    //Set the database context and execute the query
    query.Context = Context;
    query.Execute();

Address 查询仅包含针对所有持久化 CustomerAddress Address 对象具有匹配地址 ID 的结果。每个查询都包含一个 Results 集合,其中包含相关的对象实例。

通过这种方法,可以将特定的查询逻辑封装到一个新的 Query 类中,并根据数据提供者的允许连接任意数量的其他 Query 实例。Query 的列和条件可以在运行时修改,从而提供更大的灵活性——唯一的查询签名可确保动态创建存储过程并在可能时重用。

是什么让 Objecto 与众不同?

Objecto 致力于开发新的业务层类。需要注意的是,它是一个组件框架,而不是开发工具。持久化对象的逻辑随应用程序一起移动,其他开发人员可以在没有原始源代码、XML 映射文件或开发工具的情况下修改和增强您的应用程序。此外,您可以将应用程序代码交付给客户,而无需担心数据库设置或部署。不再需要创建数据库的脚本,也不再需要为重新同步开发和生产系统之间的不同数据库架构而烦恼。

Objecto 从头开始编写,用于通过面向服务的体系结构进行访问,或在公司网络中使用 .NET Remoting。Objecto 的企业版包含一个 Remoting Provider,可以使包含业务对象的程序集通过 Remoting 可用,而无需 .NET Remoting 命名空间通常带来的复杂性和技术挑战。支持客户端激活对象、有状态或单调用服务器激活对象,从而能够跨多个服务器在集群中进行横向扩展。

最后,Objecto 允许您在开发人员最喜欢的环境中编写整个应用程序——Microsoft Visual Studio 2005。因为您只需在一个地方定义数据结构,并且数据提供者为您管理数据架构和数据访问代码,所以您会感到编程天堂般的体验。

评估 Objecto

Objecto 标准版对开发人员完全免费,并且没有运行时版税。Objecto 通过 Crainiate 社区论坛 提供支持,或者可以通过购买支持计划来获得支持。下方的下载包含程序员指南和全面的参考文件。

关于 Crainiate

Crainiate 致力于为使用 Microsoft .NET Framework 的开发人员构建高质量、功能丰富、易于使用的组件。我们通过将对技术的喜爱与我们的创造力以及对 Internet 和 Windows 开发的深刻理解相结合,提供强大而创新的产品。您可以 在此处 访问我们的网站。

© . All rights reserved.