实现继承--映射中的Subclass
什么叫subclass?举个例子,用户有一般用户与管理用户。她们都记录在用户表中,通过一个字段来标识是一般用户还是管理用户。我们继续这个例子。
用一个表Users保存一般用户与管理员信息,标识的字段是一个字符型,名为UserKind,值为user的是一般用户,值为admin为管理员;看一下
代码
输出数据结构
持久化对象
检索
结果
obj1 is User
obj2 is Admin.
直接查询一般用户
查询过程
用一个表Users保存一般用户与管理员信息,标识的字段是一个字符型,名为UserKind,值为user的是一般用户,值为admin为管理员;看一下
代码
/// <summary>
/// 用户
/// </summary>
public class Users
{
public int ID;
public string Name;
/// <summary>
/// 构造函数
/// </summary>
public Users()
{
}
}
/// <summary>
/// 一般用户
/// </summary>
public class User:Users
{
public User()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
}
/// <summary>
/// 管理员。
/// </summary>
public class Admin:Users
{
public Admin()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
}
/// 用户
/// </summary>
public class Users
{
public int ID;
public string Name;
/// <summary>
/// 构造函数
/// </summary>
public Users()
{
}
}
/// <summary>
/// 一般用户
/// </summary>
public class User:Users
{
public User()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
}
/// <summary>
/// 管理员。
/// </summary>
public class Admin:Users
{
public Admin()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
}
映射文件如何写,其实很简单
Users.hbm.xml
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="MyEntity.Users,MyEntity" table="Users">
<id name="ID" type="Int32">
<generator class="native" />
</id>
<discriminator column="UserKind" type="String" />
<property name="Name" type="String" not-null="true" length="50" />
<subclass name="MyEntity.Admin,MyEntity" discriminator-value="User">
</subclass>
<subclass name="MyEntity.Admin,MyEntity" discriminator-value="Admin">
</subclass>
</class>
</hibernate-mapping>
<class name="MyEntity.Users,MyEntity" table="Users">
<id name="ID" type="Int32">
<generator class="native" />
</id>
<discriminator column="UserKind" type="String" />
<property name="Name" type="String" not-null="true" length="50" />
<subclass name="MyEntity.Admin,MyEntity" discriminator-value="User">
</subclass>
<subclass name="MyEntity.Admin,MyEntity" discriminator-value="Admin">
</subclass>
</class>
</hibernate-mapping>
需要注意的只是discriminator与discriminator-value.
输出数据结构
Configuration cfg = new Configuration();
cfg.AddClass(typeof(Users));
new SchemaExport (cfg).Create(true,true);
User与Admin都不需要加到Configuration中,加的话只会引起错误。cfg.AddClass(typeof(Users));
new SchemaExport (cfg).Create(true,true);
持久化对象
Configuration cfg = new Configuration();
cfg.AddClass(typeof(Users));
_sessions = cfg.BuildSessionFactory();
User usr = new User();
usr.Name = "一般用户";
Admin ad = new Admin();
ad.Name = "管理员";
ISession session = this._sessions.OpenSession();
session.Save(usr);
session.Save(ad);
cfg.AddClass(typeof(Users));
_sessions = cfg.BuildSessionFactory();
User usr = new User();
usr.Name = "一般用户";
Admin ad = new Admin();
ad.Name = "管理员";
ISession session = this._sessions.OpenSession();
session.Save(usr);
session.Save(ad);
执行结果
NHibernate: INSERT INTO Users (Name, UserKind) VALUES (@p0, 'User'); select SCOPE_IDENTITY()
@p0 = '一般用户'
NHibernate: INSERT INTO Users (Name, UserKind) VALUES (@p0, 'Admin'); select SCOPE_IDENTITY()
@p0 = '管理员'
@p0 = '一般用户'
NHibernate: INSERT INTO Users (Name, UserKind) VALUES (@p0, 'Admin'); select SCOPE_IDENTITY()
@p0 = '管理员'
检索
ISession session = this._sessions.OpenSession();
int iID = 1;
int iID2 = 2;
object obj = session.Load(typeof(Users),iID);
object obj2 = session.Load(typeof(Users),iID2);
string str1 = "User";
string str2 = "User";
if(obj is Admin)
str1 = "Admin";
if(obj2 is Admin)
str2 = "Admin";
Console.WriteLine("obj1 is " + str1);
Console.WriteLine("obj2 is " + str2);
int iID = 1;
int iID2 = 2;
object obj = session.Load(typeof(Users),iID);
object obj2 = session.Load(typeof(Users),iID2);
string str1 = "User";
string str2 = "User";
if(obj is Admin)
str1 = "Admin";
if(obj2 is Admin)
str2 = "Admin";
Console.WriteLine("obj1 is " + str1);
Console.WriteLine("obj2 is " + str2);
结果
obj1 is User
obj2 is Admin.
直接查询一般用户
ISession session = this._sessions.OpenSession();
int iID = 1;
User usr = (User)session.Load(typeof(User),iID);
session.Close();
int iID = 1;
User usr = (User)session.Load(typeof(User),iID);
session.Close();
查询过程
NHibernate: SELECT user0_.ID as ID0_, user0_.NickName as NickName0_, user0_.Name as Name0_ FROM Users user0_ WHERE user0_.ID=@p0 and user0_.UserKind='User'
@p0 = '1'
@p0 = '1'