技术开发 频道

NBearV3 Step by Step教程——ORM篇

    Step 4 设置设计实体元数据

    4.1 切换到源代码视图。首先,我们要为除了关联实体UserGroup之外(对于关联实体,凡是标记为RelationKey的属性,会被自动认为是复合主键)的所有设计实体的主键设置PrimaryKey这个Attribute,可以为多主键实体的每个主键添加该属性。如果不正确设置主键,代码生成工具将不能正确生成数据库创建脚本。例如,对于User实体的ID属性,设置后的代码象下面这样:

[PrimaryKey] Guid ID { get; set; }

    注:大家可能有疑问,为什么这里主键ID能不能是int,并且是自增长的只读属性呢?答案是完全可以的,完全可以设置某个ID属性为下面这样,无需额外设置,它将映射到一个自增长只读的int类型的数据库字段:

[PrimaryKey] int ID { get; }

    4.2 在后面的步骤生成实体对应的数据库创建脚本时,对于数值类型,nullable类型和枚举类型,NBear能够自动将他们对应到数据库的对应类型,但是,对string类型,一般需要指定其映射到数据库时的具体类型和长度。当然,也可以不指定,如果不指定,则string类型默认被映射为nvarchar(127)。例如,对于UserProfile的ProfileContent属性,我们添加下面的Attribute,设置其映射到数据库的类型为ntext:

[SqlType("ntext")] string ProfileContent { get; set; }

    又如,对于LocalUserPhone的Number属性,我们添加下面的Attribute,设置其映射到数据库的类型为nvarchar(20):

[SqlType("nvarchar(20)")] string Number { get; set; }

    4.2 对于User的Name这个UserName类型的复合类型,我们也需要设置其SqlType,一般设为ntext,因为,默认情况下复合类型被序列化为XML,并保存于对应的数据库字段。另外,复合类型还必须使用CompoundUnit这个Attribute标记,所以User的Name属性需要被设置成下面这样:

[CompoundUnit] [SqlType("ntext")] UserName Name { get; set; }

    注:继承关系不需要特别设置,NBear可以识别接口的自然继承关系,但是,注意,不要让一个设计实体接口继承超过一个基类接口,否则,NBear将不能识别这种继承关系。换句话说,NBear不支持多根继承。之所以有这个限制是因为,后面,所有这些设计实体接口会被自动生成为class形式的实体代码,而class是不支持多根继承的。

    4.3 对于User和UserProfile的1对1关联,我们需要为User接口的Profile属性设置下面的Attributes(这些Attribues都包含于NBear.Common.Design中,因此,需要注意在代码中using NBear.Common.Design):

[FkQuery("UserID", Contained = true, LazyLoad = false)] UserProfile Profile { get; set; }

    其中,FkQuery代表这个属性是一个1对1外键关联,参数UserID表示,在UserProfile实体中,UserID为对应的外键。LazyLoad=false容易理解,表示这个属性不是知道访问才载入数据的,而是,在实例化User对象的时候,就自动载入Profile属性的数据。当然,如果需要,也可以将LazyLoad设为true。另外,可以像下面这样设置UserProfile的UserID属性为外键,则生成的数据库脚本将包含外键引用完整性检测:

[FriendKey(typeof(User))] Guid UserID { get; set; }

    4.4 对于LocalUser和LocalUserPhone的1对多关联,我们需要为LocalUser接口的Phones属性设置下面对的Attributes:

[FkQuery("UserID", Contained=true, LazyLoad=true)] LocalUserPhone[] Phones { get; set; }

    这里LocalUser和LocalUserPhones是1对多外键关联。Contained=true表示Phones跟随LocalUser级联更新。

    4.5 对于User和Group的多对多关联,我们为User.Groups属性设置下面的Attributes:

[ManyToManyQuery(typeof(UserGroup), OrderBy="{Name} DESC", LazyLoad=true)] Group[] Groups { get; set; }

    我们可以看到,和前面的1对1和1对多关联相比,多对多关联的主要区别是必须设置ManyToManyQuery的构造函数参数,指定关联实体为UserGroup。这里的OrderBy并不是必须的,如果不指定,则载入的Group按默认规则排序。

    4.6 另外,还需要设置UserGroup这个关联实体的属性如何与User和Group的属性进行关联。我们需要对UserGroup这个实体关联接口及它的属性设定下面的Attributes:

[Relation] public interface UserGroup : NBear.Common.Design.Entity { [RelationKey(typeof(User))] Guid UserID { get; set; } [RelationKey(typeof(Group))] Guid GroupID { get; set; } }

    注意,首先,关联实体必须使用Relation这个Attribute修饰。其次,每一个关联属性的用于关联的属性,必须使用RelationKey这个Attribute修饰。RelationKey的唯一参数指定这个属性关联到哪一个实体。例如,这里,UserGroup的UserID属性关联到User实体;而GroupID属性则关联到Group实体。

    4.7 对于LocalUser的Password,我们可以添加NotNull和SerializationIgnore这两个Attribute,显式地设置其对应字段为非空,并且,保证其不会被包含在默认的XML序列化中。设置到设计实体的SerializationIgnore,会在最终生成的实体中用XmlIngore标识。

[SqlType("nvarchar(50)")] [NotNull] [SerializationIgnore] string Password { get; set; }
0
相关文章