.NET Tech Blog - Find Web Hosting

Find best web hosting with coupon, professional editorial reviews and customer voted reviews.

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

认识DataQuickerORM)之二 自定义属性

(过时,请在我的Blog上参见最新文档)

本文就DataQuicker中使用到的所有public自定义属性CustomAttribute的作用及其使用方法进行介绍。

 

1AliasAttributeAttributeTargets.Property

用于指定字段/表的别名,别人主要用于当SQL中可能会发生重复名称或者需要特别指定查询结果的列名、表名,在我们的通常的查询中,比如如下SQL

SELECT EName AS EnglishName FROM Employees

EnglishName在此查询中就作为列EName的别名,我们在DataQuicker中,我们使用AliasAttribute指定某一列的默认列名,当我们没有在程序中使用.AliasName改变该列的别名时,DataQuicker默认使用该默认别名。

private FString mAddress = new FString();

       [Field("Address"), Alias(“HomeAddress”)]

       public FString Address

       {

              get

              {

                     return this.mAddress;

              }

              set

              {

                     this.mAddress.Replace(value);

              }

       }

这样,在查询中,DataQuicker会自动生成别名HomeAddress,比如

SELECT Address AS HomeAddress FROM Employees

 

对于表的别名,

private Employees mEmployees = new Employees();

[Association("EmployeeID", true, JointType.Inner), Alias(“SaleEmployees”)]

       public Employees Employees

       {

              get

              {

                     return this.mEmployees;

              }

              set

              {

                     this.mEmployees.Replace(value);

              }

       }

这样,在查询时,生成的SQL如下:

SELECT * FROM Orders

INNER JOIN Employees SaleEmployees ON SaleEmployees.EmployeeID=Orders.EmployeeID

 

当然,这是在实体层上设置,其实我们可以使用Property AliasName来动态的设置列或者表的别名。

 

2AssociationAttributeAttributeTargets.Property

用于对两个实体建立关联,类似于如下SQL中我们需要创建关联的EmployeesOrders查询,在DataQuicker中,这种关联必须是固定在实体设计中的,不能动态的将多个当表临时关联到一起。

SELECT * FROM Orders

INNER JOIN Employees ON Employees.EmployeeID=Orders.EmployeeID

对于上述的这种关联(即Employees表的主键是Orders表的外键),我们创建的实体模板如下

[Serializable, Entity("Orders"), Provider("DB1")]

       public class Orders: TableMapping

       {

              private Employees mEmployees = new Employees();

              [Association("EmployeeID", true, JointType.Inner)]

              public Employees Employees

              {

                     get

                     {

                            return this.mEmployees;

                     }

                     set

                     {

                            this.mEmployees.Replace(value);

                     }

              }

       }

构造函数public AssociationAttribute(string foreignKeyFieldName, bool isExplicit, JointType joint)的三个参数:

foreignKeyFieldName 指定Orders表的外键名称

isExplicit 指示DataQuicker是否做强制检查,当为true时,DataQuicker强制检查Orders中的外键在Employees表中必须存在,否则会抛出Exception;而它为false时,DataQuicker不会做这种检查

joint 两个实体默认的关联类型,是使用Left Join/Right Join/Inner Join,当然,这种指定在程序中可以通过子表(即Employees实体的)Property Association来进行动态改变,比如代码

Orders order = Orders.CreateInstrance();

order.Employees.Association.Joint = JointType.Left;

 

3EntityAttributeAttributeTargets.Class

用在标志实体Class映射的表名称,该名称必须是数据库中已存在的表

[Serializable, Entity("Suppliers"), Provider("DB1")]

       public class Supplier: TableMapping

       {

       }

以上示例说明实体Supplier会映射数据库中的Suppliers表。

 

4FieldAttributeAttributeTargets.Property

用在标志实体Property映射的数据列名称,该名称必须是该Property所属的实体Class对应的表中存在的字段

[Serializable, Entity("Suppliers"), Provider("DB1")]

       public class Supplier: TableMapping

       {

              private FString mCompanyName = new FString();

 

              [Field("CompanyName")]

              public FString CompanyName

              {

                     get

                     {

                            return this.mCompanyName;

                     }

                     set

                     {

                            this.mCompanyName.Replace(value);

                     }

              }

       }

以上示例说明实体Supplier中的CompanyName属性会映射数据库中Suppliers表的CompanyName字段。

 

5PrimaryAttributeAttributeTargets.Property

用于标志字段是否为主键,目前DataQuicker只支持单主键,也就是说PrimaryKey只能在同一实体Class中标记一次,否则会抛出异常。

构造函数:

public PrimaryKeyAttribute()

public PrimaryKeyAttribute(PKType type)

PKType为标记该主键的方式:

    5.1 DQIncrease DataQuicker管理该字段的自增长,该字段的数据库类型允许为int或者文本类型,DataQuicker在插入新记录时会自动取最大记录编号(转换成数值类型)并加1DataQuicker对并发进行了处理,不会存在并发问题。由于数据库在主键上通常都创建了索引,所以在这一算法中性能影响不大,推荐使用文本类型作为主键,在导数据时以免发生历史数据是非数值类型而无法导入的问题,不过文本类型会比使用int类型作为主键速度稍慢。

       5.2 Guid 使用长度为32char类型字段作为主键,DataQuicker会在新增记录时自动生成32位的GUID全球唯一码,在数据插入时,性能会比使用DQIncrease高些,但是使用Guid有无序性的特点,另外32位长度的字符串上创建索引会影响性能和造成额外的磁盘空间开销

       5.3 None DataQuicker不会对主键进行任何管理,在新增记录时需要用户进行手动设置主键值,或者主键为自增长类型,DataQuicker不推荐使用。

当使用空参数的构造函数时,DataQuicker默认为PKType.DQIncrease

 

6ProviderAttributeAttributeTargets.Class

用于标志实体所属的数据库连接,Providerapp.config配置文件中列举,在同一个应用系统中,通常可能存在多个数据库连接,在DataQuicker中,每个数据库连接其实就是对应一个Provider,一个Provider拥有一个唯一表示符ProviderName。我们在定义实体时,需要指定实体所属的Provider

[Serializable, Entity("Suppliers"), Provider("DB1")]

       public class Supplier: TableMapping

       {                      

              ……

       }

在实体Supplier上标记的ProviderDB1,它必须是在配置文件中进行了配置的,

<Providers>

       --

              Name="The unique name for provider"  (Required)

              Value="Database connection string for special database connection"      (Required)

              Type="Full name of DataQuicker provider"   (Required)

              OLEConnectionString="Database connection string for OLE connection, it's for DbSchemaCache to get schema of database"       (Required)

              Default    (Optional)

              -->

       <Provider Name="DB1"

Value="server=localhost; UID=sa; pwd=sa; database=Northwind"

Type="DataQuicker.Framework.SqlProvider"

OLEConnectionString="Data Source=localhost; User ID=sa; Password=sa; Initial Catalog=Northwind; Provider=SQLOLEDB.1">

Provider>

Providers>

在上述配置节中,Value中配置的是SqlConnection的数据库连接字符串,但是我们还设置了OLEConnectionString,是因为DataQuicker通过OLE连接来获取数据库的Schema信息。

 

7ValidateAttributeAttributeTargets.Property

标记在Property上,用于设置字段的验证表达式

构造函数public ValidateAttribute(params object[] candidator)

当标记在FString类型字段上时,candidator应为正则表达式,用于对该字段设置的值进行验证

private FString mEmail = new FString();

              ///

              /// The content of email must be the suitable format

              ///

              [Field("Email"), Validate(@"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*")]

              public FString Email

              {

                     get

                     {

                            return this.mEmail;

                     }

                     set

                     {

                            this.mEmail.Replace(value);

                     }

              }

所以,凡是对该Email属性设置的值都必须符合\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*验证

 

当标记在FIntFDecimalFDateTime等类型字段上时,表示时间/数值的大小范围

private FInt mRange = new FInt();

              ///

              /// The valid value of Range should be 0-100

              ///

              [Field("Range"), Validate(0, 100)]

              public FInt Range

              {

                     get

                     {

                            return this.mRange;

                     }

                     set

                     {

                            this.mRange.Replace(value);

                     }

              }

规定Range的合法值是0100,否则DataQuicker将抛出异常

 

如果上述代码改为:(Validate的参数只有一个)

private FInt mRange = new FInt();

              ///

              /// The valid value of Range should be 0-100

              ///

              [Field("Range"), Validate(0)]

              public FInt Range

              {

                     get

                     {

                            return this.mRange;

                     }

                     set

                     {

                            this.mRange.Replace(value);

                     }

              }

规定Range的合法值必须大于0,否则DataQuicker将抛出异常

 

 

posted on 2005-08-02 19:03  Eunge  阅读(935)  评论(0)    收藏  举报