24.2.5 特性应用完整示例
代码清单24-31 是特性应用的完整示例,模拟了一个O/R Mapping框架中实体和数据库映射的方法,其中涉及两个特性:
❑TableAttribute
❑ColumnAttribute
在示例中,我们定义了上述两个特性,分别是在表和类之间建立映射的TableAttribute特性,以及在字段属性之间建立映射的ColumnAttribute特性。如果读者曾经使用过Hibernate或者NHibernate那么将会很容易理解,没有使用过也没关系,我将尽量使用简单的语言来解释为什么要做这种映射。
O/R Mapping意思就是“对象/关系映射”,就是将通过ADO.NET查询出的基于“记录”的数据转换成“对象”。换句话说,就是将数据库里的一条条的数据转换为一个对象的集合,转换成对象可以更加方便地处理数据。好了,简单介绍了对象、关系映射,那么现在就来说明下这两个特性的用途。
TableAttribute特性包含两个数据:数据库表名和是否能加载,通过这个特性就能获取当前类和哪张数据库表进行映射,以及数据的加载方式。
ColumnAttribute特性包含四个数据:列名、数据类型、数据长度以及是否可以为空。
更多的请参看代码清单24-31。
代码清单24-31 特性应用完整示例
using System;
using System.Reflection;
using System.Diagnostics;
namespace ProgrammingCSharp4
{
class AttributeSample
{
public static void Main(string[]args)
{
Book book=new Book();
Type type=book.GetType();
TableAttribute tableAttribute=(TableAttribute)type.GetCustomAttributes(false)[0];
Console.WriteLine("Class:{0}",type.Name);
Console.WriteLine("table={0}",tableAttribute.Name);
PropertyInfo[]infos=type.GetProperties();
foreach(PropertyInfo prop in infos)
{
object[]attributes=prop.GetCustomAttributes(false);
Console.Write("-".PadRight(80,'-'));
System.Console.WriteLine("Property:{0}",prop.Name);
foreach(Attribute attribute in attributes)
{
if(attribute is ColumnAttribute)
{
ColumnAttribute columnAttribute=attribute as ColumnAttribute;
string columnName=columnAttribute.ColumnName;
string columnType=columnAttribute.ColumnType;
int columnLength=columnAttribute.ColumnLength;
bool columnIsNull=columnAttribute.IsNull;
Console.WriteLine("columnName={0},columnType={1},columnLength={2},columnIsNull={3}",columnName,columnType,
columnLength,columnIsNull);
}
}
}
}
}
[Table("TBook",IsLazy=true)]
class Book
{
[Column("bookId","int",ColumnLength=8,IsNull=true)]
public int BookId
{
get;
set;
}
[Column("bookName","varchar",ColumnLength=25,IsNull=true)]
public string BookName
{
get;
set;
}
[Column("bookAuthor","varchar",ColumnLength=15,IsNull=true)]
public string Author
{
get;
set;
}
[Column("bookPubYear","datetime",ColumnLength=10,IsNull=true)]
public DateTime PubYear
{
get;
set;
}
}
[AttributeUsage(AttributeTargets.Class,AllowMultiple=false,Inherited=false)]
public class TableAttribute:Attribute
{
public bool IsLazy;
private string_name;
public TableAttribute(string name)
{
this._name=name;
}
public string Name
{
get
{
return_name;
}
}
}
[AttributeUsage(AttributeTargets.Property,AllowMultiple=false,Inherited=false),]
public class ColumnAttribute:Attribute
{
private string_columnName;
private string_columnType;
public ColumnAttribute(string columnName,string columnType)
{
_columnName=columnName;
_columnType=columnType;
}
public string ColumnName
{
get
{
return_columnName;
}
}
public string ColumnType
{
get
{
return_columnType;
}
}
public int ColumnLength
{
get;
set;
}
public bool IsNull
{
get;
set;
}
}
}
上述代码的运行结果为:
Class:Book
table=TBook
Property:BookId
columnName=bookId,columnType=int,columnLength=8,columnIsNull=True
Property:BookName
columnName=bookName,columnType=varchar,columnLength=25,columnIsNull=True
Property:Author
columnName=bookAuthor,columnType=varchar,columnLength=15,columnIsNull=True
Property:PubYear
columnName=bookPubYear,columnType=datetime,columnLength=10,columnIsNull=True
请按任意键继续……