认识DataQuicker(ORM)之二 自定义属性
(过时,请在我的Blog上参见最新文档)本文就DataQuicker中使用到的所有public自定义属性CustomAttribute的作用及其使用方法进行介绍。
1、AliasAttribute:AttributeTargets.Property
用于指定字段/表的别名,别人主要用于当SQL中可能会发生重复名称或者需要特别指定查询结果的列名、表名,在我们的通常的查询中,比如如下SQL:
SELECT
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
对于表的别名,
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来动态的设置列或者表的别名。
2、AssociationAttribute:AttributeTargets.Property
用于对两个实体建立关联,类似于如下SQL中我们需要创建关联的Employees和Orders查询,在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;
3、EntityAttribute:AttributeTargets.Class
用在标志实体Class映射的表名称,该名称必须是数据库中已存在的表
[Serializable, Entity("Suppliers"), Provider("DB1")]
public class Supplier: TableMapping
{
}
以上示例说明实体Supplier会映射数据库中的Suppliers表。
4、FieldAttribute:AttributeTargets.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字段。
5、PrimaryAttribute:AttributeTargets.Property
用于标志字段是否为主键,目前DataQuicker只支持单主键,也就是说PrimaryKey只能在同一实体Class中标记一次,否则会抛出异常。
构造函数:
public PrimaryKeyAttribute()
public PrimaryKeyAttribute(PKType type)
PKType为标记该主键的方式:
5.1 DQIncrease - 由DataQuicker管理该字段的自增长,该字段的数据库类型允许为int或者文本类型,DataQuicker在插入新记录时会自动取最大记录编号(转换成数值类型)并加1,DataQuicker对并发进行了处理,不会存在并发问题。由于数据库在主键上通常都创建了索引,所以在这一算法中性能影响不大,推荐使用文本类型作为主键,在导数据时以免发生历史数据是非数值类型而无法导入的问题,不过文本类型会比使用int类型作为主键速度稍慢。
5.2 Guid - 使用长度为32的char类型字段作为主键,DataQuicker会在新增记录时自动生成32位的GUID全球唯
5.3 None - DataQuicker不会对主键进行任何管理,在新增记录时需要用户进行手动设置主键值,或者主键为自增长类型,DataQuicker不推荐使用。
当使用空参数的构造函数时,DataQuicker默认为PKType.DQIncrease
6、ProviderAttribute:AttributeTargets.Class
用于标志实体所属的数据库连接,Provider在app.config配置文件中列举,在同一个应用系统中,通常可能存在多个数据库连接,在DataQuicker中,每个数据库连接其实就是对应一个Provider,一个Provider拥有一个唯一表示符ProviderName。我们在定义实体时,需要指定实体所属的Provider。
[Serializable, Entity("Suppliers"), Provider("DB1")]
public class Supplier: TableMapping
{
……
}
在实体Supplier上标记的Provider:DB1,它必须是在配置文件中进行了配置的,
<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信息。
7、ValidateAttribute:AttributeTargets.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+)*验证
当标记在FInt、FDecimal、FDateTime等类型字段上时,表示时间/数值的大小范围
private FInt mRange = new FInt();
///
/// The valid value of Range should be 0-100
///
[Field("Range"), Validate(0, 100)]
public
{
get
{
return this.mRange;
}
set
{
this.mRange.Replace(value);
}
}
规定Range的合法值是0到100,否则DataQuicker将抛出异常
如果上述代码改为:(Validate的参数只有一个)
private FInt mRange = new FInt();
///
/// The valid value of Range should be 0-100
///
[Field("Range"), Validate(0)]
public
{
get
{
return this.mRange;
}
set
{
this.mRange.Replace(value);
}
}
规定Range的合法值必须大于0,否则DataQuicker将抛出异常

浙公网安备 33010602011771号