本文演示对一组继承关系的实体的元数据设置及自动生成数据库创建脚本的过程。

如上图所示,在vs2005中使用内置的可视化类设计器设计实体结构如上,注意,所有的实体都是接口。关于如何创建简单的接口式实体,请参见用户手册。对应的代码如下:
[Table(IsContract = true)]2
public interface IdentableEntity : IEntity3

{4
[PrimaryKey]5

int Id
{ get; set; }6

string Name
{ get; set; }7
}8

9
[Table(IsContract = true)]10
public interface Loginable : IEntity11

{12

string LoginId
{ get; set; }13
}14

15
[Table(IsContract = true)]16
public interface PasswordLoginable : Loginable17

{18

string Password
{ get; set; }19
}20

21
[Table(IsContract = true)]22
public interface PrivilegeAssignable : IEntity23

{24

int PrivilegeOwnerId
{ get; set; }25
}26

27
[Table("User", UpdateTableName = "User", UpdateExtendedOnly = true)]28
public interface User : IdentableEntity, PrivilegeAssignable29

{30
}31

32
[Table("select User.*, LocalUser.LoginId, LocalUser.Password from LocalUser inner join User on LocalUser.Id = User.Id", UpdateTableName = "LocalUser", IsView = true, UpdateExtendedOnly = true)]33
public interface LocalUser : PasswordLoginable, User34

{35
}36

37
[Table("select User.*, AgentUser.LoginId from AgentUser inner join User on AgentUser.Id = User.Id", UpdateTableName = "AgentUser", IsView = true, UpdateExtendedOnly = true)]38
public interface AgentUser : Loginable, User39

{40
}41

42
[Table("select User.* from GhostUser inner join User on GhostUser.Id = User.Id", UpdateTableName = "GhostUser", IsView = true, UpdateExtendedOnly = true)]43
public interface GhostUser : User44

{45
}46

47
[Table("UserGroup", UpdateTableName = "UserGroup", UpdateExtendedOnly = true)]48
public interface UserGroup : IdentableEntity, PrivilegeAssignable49

{50

string Comment
{ get; set; }51
}注意,以上代码中已经包含了以特性方式设置的元数据了,如果使用了外部配置文件方式设置元数据,则这些特性设置是不必须的。更进一步说,当同时使用特性方式和外部配置文件方式为实体设置了元数据时,外部文件中的设置将覆盖直接写在代码中的特性方式的设置。这样我们就能在无需重新编译的情况下,修改外部实体配置文件,修改实体和数据库表的对应,修改数据库结构,甚至改用不同类型的数据库。
下面,我们使用Entity Configurator工具载入(从菜单选择File-〉Load-〉Load Assembly)编译后的包含以上实体的程序集,修改实体及实体属性的元数据,如果需要生成数据库创建脚本,则一定要设置每个实体属性的DbType属性,指定生成的数据库表中对应列的数据类型。配置完成后,可以使用File-〉Save Config将配置信息保存到config文件(可以直接保存到应用程序的Web.config或App.config,工具只会添加实体配置代码,不会删除config文件中的其他代码)。
下面是Save Config为上面的实体生成的配置文件内容:
?<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="EntityConfiguration" type="NBear.Common.EntityConfigurationSection, NBear.Common" />
</configSections>
<EntityConfiguration>
<Entity fullName="Sample_Entity_Configuration_By_Entity_Configurator.AgentUser" isView="true" updateExtendedOnly="true" updateTableName="AgentUser">
<Name>select User.*, AgentUser.LoginId from AgentUser inner join User on AgentUser.Id = User.Id</Name>
</Entity>
<Entity fullName="Sample_Entity_Configuration_By_Entity_Configurator.GhostUser" isView="true" updateExtendedOnly="true" updateTableName="GhostUser">
<Name>select User.* from GhostUser inner join User on GhostUser.Id = User.Id</Name>
</Entity>
<Entity fullName="Sample_Entity_Configuration_By_Entity_Configurator.IdentableEntity" isView="true" isContract="true">
<Columns>
<Column propertyName="Id" dbType="int" isPrimaryKey="true" />
<Column propertyName="Name" dbType="nvarchar(50)" />
</Columns>
</Entity>
<Entity fullName="Sample_Entity_Configuration_By_Entity_Configurator.IdFactory">
<Columns>
<Column propertyName="NextId" dbType="int" />
</Columns>
</Entity>
<Entity fullName="Sample_Entity_Configuration_By_Entity_Configurator.LocalUser" isView="true" updateExtendedOnly="true" updateTableName="LocalUser">
<Name>select User.*, LocalUser.LoginId, LocalUser.Password from LocalUser inner join User on LocalUser.Id = User.Id</Name>
</Entity>
<Entity fullName="Sample_Entity_Configuration_By_Entity_Configurator.Loginable" isView="true" isContract="true">
<Columns>
<Column propertyName="LoginId" dbType="nvarchar(50)" />
</Columns>
</Entity>
<Entity fullName="Sample_Entity_Configuration_By_Entity_Configurator.PasswordLoginable" isView="true" isContract="true">
<Columns>
<Column propertyName="Password" dbType="nvarchar(50)" />
</Columns>
</Entity>
<Entity fullName="Sample_Entity_Configuration_By_Entity_Configurator.PrivilegeAssignable" isView="true" isContract="true">
<Columns>
<Column propertyName="PrivilegeOwnerId" dbType="int" />
</Columns>
</Entity>
<Entity fullName="Sample_Entity_Configuration_By_Entity_Configurator.User" updateExtendedOnly="true" updateTableName="User">
<Name>User</Name>
</Entity>
<Entity fullName="Sample_Entity_Configuration_By_Entity_Configurator.UserGroup" updateExtendedOnly="true" updateTableName="UserGroup">
<Name>UserGroup</Name>
<Columns>
<Column propertyName="Comment" dbType="nvarchar(50)" />
</Columns>
</Entity>
</EntityConfiguration>
</configuration>
也可以使用File-〉Load-〉Load Config载入已存在的config文件。注意,载入config文件时,config文件中的元数据配置信息,会覆盖当前编辑中的实体元数据信息。
使用Database-〉Generate Database Creation Script可以生成创建所有数据表的.sql数据库脚本(本工具目前仅支持Sql Server数据库的数据脚本生成)。
对应于以上实体的生成的数据库创建脚本如下:
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[AgentUser]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[AgentUser]
GO
CREATE TABLE [dbo].[AgentUser] (
[LoginId] nvarchar(50),
[Id] int NOT NULL,
[Name] nvarchar(50),
[PrivilegeOwnerId] int
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[AgentUser] WITH NOCHECK ADD
CONSTRAINT [PK_AgentUser] PRIMARY KEY CLUSTERED
(
[Id]
) ON [PRIMARY]
GO
CREATE INDEX [Id] ON [dbo].[AgentUser]([Id]) ON [PRIMARY]
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[GhostUser]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[GhostUser]
GO
CREATE TABLE [dbo].[GhostUser] (
[Id] int NOT NULL,
[Name] nvarchar(50),
[PrivilegeOwnerId] int
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[GhostUser] WITH NOCHECK ADD
CONSTRAINT [PK_GhostUser] PRIMARY KEY CLUSTERED
(
[Id]
) ON [PRIMARY]
GO
CREATE INDEX [Id] ON [dbo].[GhostUser]([Id]) ON [PRIMARY]
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[IdFactory]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[IdFactory]
GO
CREATE TABLE [dbo].[IdFactory] (
[NextId] int
) ON [PRIMARY]
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[LocalUser]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[LocalUser]
GO
CREATE TABLE [dbo].[LocalUser] (
[Password] nvarchar(50),
[LoginId] nvarchar(50),
[Id] int NOT NULL,
[Name] nvarchar(50),
[PrivilegeOwnerId] int
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[LocalUser] WITH NOCHECK ADD
CONSTRAINT [PK_LocalUser] PRIMARY KEY CLUSTERED
(
[Id]
) ON [PRIMARY]
GO
CREATE INDEX [Id] ON [dbo].[LocalUser]([Id]) ON [PRIMARY]
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[User]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[User]
GO
CREATE TABLE [dbo].[User] (
[Id] int NOT NULL,
[Name] nvarchar(50),
[PrivilegeOwnerId] int
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[User] WITH NOCHECK ADD
CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED
(
[Id]
) ON [PRIMARY]
GO
CREATE INDEX [Id] ON [dbo].[User]([Id]) ON [PRIMARY]
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[UserGroup]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[UserGroup]
GO
CREATE TABLE [dbo].[UserGroup] (
[Comment] nvarchar(50),
[Id] int NOT NULL,
[Name] nvarchar(50),
[PrivilegeOwnerId] int
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[UserGroup] WITH NOCHECK ADD
CONSTRAINT [PK_UserGroup] PRIMARY KEY CLUSTERED
(
[Id]
) ON [PRIMARY]
GO
CREATE INDEX [Id] ON [dbo].[UserGroup]([Id]) ON [PRIMARY]
GO
可以直接在Sql Server查询分析器中执行生成的脚本,创建所有对应的表。
下面是Entity Configurator工具的主界面。更多关于Entity Configurator介绍,请参见用户手册。