5.1 使用特性
在您的应用程序中定义一个实体类和普通对象类没什么区别,但是实体类需要附加特殊的说明来阐述实体类和数据库表格之间的关联。这些说明就是实体类的自定义特性。只有在您使用DLinq时,这些类的特性才会有意义。这和.NET framework中的XML序列化特性机制是一样的。DLinq利用这些“数据”特性获取足够的信息来将实体转化为对数据库的SQL查询以及将实体变化转化为SQL insert,update和delete命令。
5.1.1 Database特性
如果没有指定Connection,Database特性用于指定默认的数据库名称。Database特性应用到强类型的DataContext。这个特性是可选的。
属性 |
类型 |
描述 |
Name |
String |
指定数据库的名称。这个特性仅在没有指定Connection时有效。如果在DataContext声明中没有指定Database特性,并且没有指定Connection,那么数据库的名称同DataContext类名。 |
[Database(Name="Database#5")]
publicclassDatabase5 : DataContext {
...
}
5.1.2 Table特性
Table特性用于指定实体类相关联的数据库表格。拥有Table特性的实体类被DLinq做了特殊处理。
属性 |
类型 |
描述 |
Name |
String |
指定数据库表格的名称。如果没有指定,DLinq假设数据库表格的名称同实体类的名称。 |
[Table(Name="Customers")]
publicclassCustomer {
...
}
5.1.3 Column特性
Column特性用于指定实体类成员对应的数据库表格的列。它可用于任何public、private或者internal成员或者属性。只有被标识了Column特性的成员才会被DLinq保存到据到数据库中。
属性 |
类型 |
描述 |
Name |
String |
表格或视图列的名称。如果没有被指定,列的名称同类的成员的名称。 |
Storage |
String |
用于数据存储的成员名称。这个属性告诉DLinq怎样忽略数据成员的public属性访问器,而是同原始的数据成员进行数据交换。如果没有被指定,DLinq使用public访问器的get和set方法。 |
DBType |
String |
指定数据库类型和修饰。使用T-SQL语法。如果没有被指定,则根据成员的类型来推断数据库的列类型。这个属性只在您需要调用CreateDatabase()来新建一个数据库实例的时候才有意义。 |
Id |
Bool |
如果为true,则表明这个成员映射到表格的主键。如果实体类中有多个成员被指定了Id特性,那么这些成员所映射的列共同组成了表格的主键。至少需要指定一个成员具有这个特性,并将之映射到相应表格/视图中的主键或者唯一约束键。DLinq不支持无唯一约束键的表格/视图 |
AutoGen |
Boolean |
表示这个成员列的值是否是数据库自动产生的。指定AutoGen=true的主键的DBType也被指定为IDENTITY。SubmitChanges()被调用实现插入行后AutoGen的成员值会被立即同步更新。 |
IsVersion |
Boolean |
表示这个成员列是否有一个数据库时间戳或版本号。相应行的每次更新,版本号会递增,时间戳列会被更新。某行被更新后,IsVersion=true的成员会被立即更新。SubmitChanges()被调用后,成员值会被立即更新。 |
UpdateCheck |
UpdateCheck |
指定DLinq怎样利用“乐观式并发控制”来进行冲突检测。如果没有任何成员被指定为IsVersion=true,则比较原始成员值和当前的数据库状态类进行冲突检测。您可以为每个成员指定UpdateCheck枚举值,从而控制它们怎样用于DLinq的冲突检测。 Always – 总是使用此列进行冲突检测 |
IsDiscriminator |
Boolean |
指定这个类成员是否为继承层次的标识值 |
一个典型的实体类将在public属性上使用Column特性,而将实际的值保存到某个private成员中。
private string _city;
[Column(Storage="_city", DBType="NVarChar(15)")]
public string City {
get { ... }
set { ... }
}
DBType声明数据库列元数据类型, 仅用于CreateDatabase()创建数据库。另外,类型字符串的长度不可以超过15个字符。
标识为数据库主键的成员的往往是通过数据库自动产生的。
private string _orderId;
[Column(Storage="_orderId", Id=true, AutoGen=true,
DBType="int NOT NULL IDENTITY")]
public string OrderId {
get { ... }
set { ... }
}
如果您确实需要指定主键的DBType,务必包含IDENTITY修饰。否则DLinq不会递增指定DBType自定义成员的值。尽管如此,当调用CreateDatabase()方法创建数据库时,如果DBType没有被指定,那么DLinq默认指定了IDENTITY。
同样地,如果IsVersion属性值为true,那么DBType必须指定版本号或者时间戳列的正确修饰。如果DBType没有被指定,那么DLinq将推断出正确的修饰。
您能够控制与自动生成列、版本戳列或者映射到任何列的成员的访问。您可以通过指定成员的访问限定符来隐藏甚至限制对其的访问。
private string _customerId;
[Column(Storage="_customerId", DBType="NCHAR(5) ")]
public string CustomerID {
get { ... }
}
即便我们通过不定义的Order的CustomerID属性的set方法来定义一个只读属性。但DLinq仍旧可以通过制定为存储字段的私有成员来设置属性的值。
您也可以设置某个成员为private,让它完全不可见,但设置了这个成员的Column特性。这可以让这个实体类封装必要的业务逻辑而不暴露给外部。尽管private成员值可以被更新,但在语言集成查询中您还是不能访问它。
默认情况下,所有的成员都参与乐观式并发冲突检测。您可以指定某个成员的UpdateCheck值来控制其并发冲突检测行为。
[Column(Storage="_city", UpdateCheck=UpdateCheck.WhenChanged)]
public string City {
get { ... }
set { ... }
}
下面的表格显示了数据库类型和CLR类型之间的映射。下面的映射表是推荐的,并不是强制的。您可以参考此表来获取到某个CLR类型所映射的数据库列类型。
数据库类型 |
.NET CLR 类型 |
描述 |
bit, tinyint, smallint, int, bigint |
Byte, Int16, Uint16, Int32, Uint32, Int64, Uint64 |
值转化的时候可能有损失。值可能不会被圆整 |
Bit |
Boolean |
|
decimal, numeric, smallmoney, money |
Decimal |
值范围差异可能导致转化损失,可能不会被圆整 |
real, float |
Single, double |
精度有差异 |
char, varchar, text, nchar, nvarchar, ntext |
String |
区域可能不同 |
datetime, smalldatetime |
DateTime |
不同的精度可能导致转化损失和圆整问题 |
Uniqueidentifier |
Guid |
不同的排序规则。排序结果不可预期 |
Timestamp |
Byte[], Binary |
字节数组被视为标量值。用户负责分配足够的内存来构造。字节数组可视为是不可变的,并且值变化不被跟踪。 |
binary, varbinary |
Byte[], Binary |
Binary类型在System.Data.DLinq 中,它的本质是一个不可变的字节数组。
5.1.4 Association特性
Association特性用于指定数据库关联属性,如外键-主键关联。
属性 |
类型 |
描述 |
Name |
String |
关联的名称,往往同数据外键约束的名称。用于在调用CreateDatabase()创建数据库实例时产生相关的约束。也用于区分引用同一个目标实体类的单个实体类的多个关联。在这种情况下,关联的实体两边的关联属性(如果两边都有定义)都必须使用相同的名称。 |
Storage |
String |
用于存储关联的成员名称。如果被指定了,它告诉DLinq怎样忽略数据成员的public属性访问器,而使用原始数据成员值进行存储。如果没有被指定,DLinq使用public属性访问器的set和get来访问数据成员值。我们推荐,所有的关联成员都表示为属性,而存储使用原始的数据成员值。 |
ThisKey |
String |
逗号分开的一个或者多个实体类成员的名称列表,用于表示关联中This端的键值。如果没有被指定,这个键值为实体类中指定为主键的成员。 |
OtherKey |
String |
逗号分开的一个或者多个目标实体类成员的名称列表,用于表示关联中被Other端的键值。如果没有被指定,这个键值为相关联实体类中指定为主键的成员。 |
Unique |
Boolean |
True表示外键上的唯一性约束,隐含表示1:1关联关系。这个属性很少使用,因为数据库中很少有1:1的关联。大部分实体模型都使用1:n关联即便它被应用程序员指定为1:1关联。 |
IsParent |
Boolean |
True表示关联的Other 端是This端的父亲。对于外键-主键关联,拥有外键的为儿子,拥有主键的为父亲。 |
关联属性或表示对另外一个实体的单一引用,或表示对另外一个实体集合的引用。单一引用必须表示为EntityRef<T>值类型来存储实际的引用。DLinq使用EntityRef类型来实现“延迟加载”。
classOrder
{
...
privateEntityRef<Customer> _Customer;
[Association(Name="FK_Orders_Customers", Storage="_Customer",
ThisKey="CustomerID")]
publicCustomer Customer {
get { return