博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[导入]Castle ActiveRecord学习记录 - 处理继承关系
阅读量:4966 次
发布时间:2019-06-12

本文共 6184 字,大约阅读时间需要 20 分钟。

  在面向对象的设计中继承是少不了的,那么如何在AR里来设计有继承关系的实体类呢?查看相关文档并做了一些尝试,例子如下(例子很简陋,仅是单纯考虑继承的实现)。其中有理解错误的地方还肯请大家指正。

一、使用 subclass

 
[ActiveRecord(
"
Entity
"
), JoinedBase]
public
class
Entity : ActiveRecordBase {
private
int
id;
private
string
name;
public
Entity() { } [PrimaryKey(PrimaryKeyType.Assigned,
"
id
"
)]
public
int
Id {
get
{
return
id; }
set
{ id
=
value; } } [Property]
public
string
Name {
get
{
return
name; }
set
{ name
=
value; } }
public
new
static
void
DeleteAll() { ActiveRecordBase.DeleteAll(
typeof
(Entity)); }
public
new
static
Entity[] FindAll() {
return
(Entity[])ActiveRecordBase.FindAll(
typeof
(Entity)); }
public
new
static
Entity Find(
int
id) {
return
(Entity)ActiveRecordBase.FindByPrimaryKey(
typeof
(Entity), id); } } [ActiveRecord(
"
EntityCompany
"
)]
public
class
CompanyEntity : Entity {
private
byte
company_type;
private
int
comp_id; [JoinedKey(
"
comp_id
"
)]
public
int
CompId {
get
{
return
comp_id; }
set
{ comp_id
=
value; } } [Property(
"
company_type
"
)]
public
byte
CompanyType {
get
{
return
company_type; }
set
{ company_type
=
value; } }
public
new
static
void
DeleteAll() { ActiveRecordBase.DeleteAll(
typeof
(CompanyEntity)); }
public
new
static
CompanyEntity[] FindAll() {
return
(CompanyEntity[])ActiveRecordBase.FindAll(
typeof
(CompanyEntity)); }
public
new
static
CompanyEntity Find(
int
id) {
return
(CompanyEntity)ActiveRecordBase.FindByPrimaryKey(
typeof
(CompanyEntity), id); } } [ActiveRecord(
"
EntityPerson
"
)]
public
class
PersonEntity : Entity {
private
int
person_id; [JoinedKey(
"
person_id
"
)]
public
int
PersonId {
get
{
return
person_id; }
set
{ person_id
=
value; } }
public
new
static
void
DeleteAll() { ActiveRecordBase.DeleteAll(
typeof
(PersonEntity)); }
public
new
static
PersonEntity[] FindAll() {
return
(PersonEntity[])ActiveRecordBase.FindAll(
typeof
(PersonEntity)); }
public
new
static
PersonEntity Find(
int
id) {
return
(PersonEntity)ActiveRecordBase.FindByPrimaryKey(
typeof
(PersonEntity), id); } }

这个例子中,首先在基类Entity的属性标签加上"JoinedBase"参数(表示为一个或多个subclass的父类),然后在子类CompanyEntity和PersonEntity中分别增加一个属性CompId和PersonId并打上"JoinedKey"属性标签(它们在数据表中体现为外键,通过它把子类与基类的表关联起来)。
这种方法会将基类映射到一张数据表,子类分别映射到单独的一张数据表(表里不包含基类的属性值,这些值都在基类映射的数据表中)。持久化子类的时候,相关信息分别保存到基类和子类映射的数据表中。
测试一下:

 
private
void
TestSubclass() { PersonEntity person
=
new
PersonEntity(); person.Id
=
500
; person.Name
=
"
Allen
"
; person.Create(); CompanyEntity company
=
new
CompanyEntity(); company.Id
=
100
; company.Name
=
"
SomeName
"
; company.Create(); Entity en
=
Entity.Find(
100
);
string
str
=
en.ToString()
+
"
, ID=
"
+
en.Id
+
"
, Name=
"
+
en.Name; CompanyEntity comp
=
CompanyEntity.Find(
100
); str
+=
"
\r\n
"
+
comp.ToString()
+
"
, ID=
"
+
comp.Id.ToString()
+
"
, CompId=
"
+
comp.CompId.ToString()
+
"
, Name=
"
+
comp.Name; PersonEntity pers
=
PersonEntity.Find(
500
); str
+=
"
\r\n
"
+
pers.ToString()
+
"
, ID=
"
+
pers.Id.ToString()
+
"
, PersonId=
"
+
pers.PersonId.ToString()
+
"
, Name=
"
+
pers.Name; MessageBox.Show(str); }

显示结果:

xx.CompanyEntity, ID=100, Name=SomeName
xx.CompanyEntity, ID=100, CompId=0, Name=SomeName
xx.PersonEntity, ID=500, PersonId=0, Name=Allen
这里很奇怪的是 CompId和PersonId 应该和 ID 是相同的值,但取出来却都是0。 不知道是为什么...

二、使用 Discriminator

 
[ActiveRecord(
"
EntityBase
"
, DiscriminatorColumn
=
"
type
"
, DiscriminatorType
=
"
String
"
, DiscriminatorValue
=
"
Entity
"
)]
public
abstract
class
EntityBase : ActiveRecordBase
<
EntityBase
>
{
private
int
_id;
private
string
_name;
public
EntityBase() { }
public
EntityBase(
string
name) {
this
._name
=
name; } [PrimaryKey(PrimaryKeyType.Native,
"
id
"
)]
public
int
ID {
get
{
return
_id; }
set
{ _id
=
value; } } [Property(
"
name
"
)]
public
string
Name {
get
{
return
_name; }
set
{ _name
=
value; } } } [ActiveRecord(DiscriminatorValue
=
"
blog
"
)]
public
class
BlogEntity : EntityBase {
private
IList _posts;
public
BlogEntity() {
this
._posts
=
new
ArrayList(); }
public
BlogEntity(
string
name) :
base
(name) { } [HasMany(
typeof
(PostEntity), Table
=
"
Entity
"
, ColumnKey
=
"
post_of
"
, Cascade
=
ManyRelationCascadeEnum.All)]
public
IList Posts {
get
{
return
_posts; }
set
{ _posts
=
value; } }
public
new
static
void
DeleteAll() { ActiveRecordBase
<
BlogEntity
>
.DeleteAll(); }
public
new
static
BlogEntity[] FindAll() {
return
ActiveRecordBase
<
BlogEntity
>
.FindAll(); }
public
static
BlogEntity Find(
int
id) {
return
ActiveRecordBase
<
BlogEntity
>
.Find(id); }
public
static
BlogEntity TryFind(
int
id) {
return
ActiveRecordBase
<
BlogEntity
>
.TryFind(id); } } [ActiveRecord(DiscriminatorValue
=
"
post
"
)]
public
class
PostEntity : EntityBase {
private
BlogEntity _blog;
public
PostEntity() { }
public
PostEntity(
string
name) :
base
(name) { } [BelongsTo(
"
post_of
"
)]
public
BlogEntity Blog {
get
{
return
_blog; }
set
{ _blog
=
value; } }
public
new
static
void
DeleteAll() { ActiveRecordBase
<
PostEntity
>
.DeleteAll(); }
public
new
static
PostEntity[] FindAll() {
return
ActiveRecordBase
<
PostEntity
>
.FindAll(); }
public
static
PostEntity Find(
int
id) {
return
ActiveRecordBase
<
PostEntity
>
.Find(id); }
public
static
PostEntity TryFind(
int
id) {
return
ActiveRecordBase
<
PostEntity
>
.TryFind(id); } }

这种方法会将所有的信息都映射到一个数据表中,通过鉴别器的值DiscriminatorValue来区分各个类的实例(数据表中的一条记录)。

运行下面的代码:

 
private
void
TestDiscriminator() {
for
(
int
i
=
1
; i
<
6
; i
++
) { BlogEntity blog
=
new
BlogEntity(
"
blog-
"
+
i.ToString()); blog.Create(); } PostEntity post1
=
new
PostEntity(
"
post_01
"
); PostEntity post2
=
new
PostEntity(
"
post_02
"
);
using
(TransactionScope tran
=
new
TransactionScope()) {
try
{ BlogEntity blog2
=
BlogEntity.Find(
2
); blog2.Name
=
"
Dotnet Fantasy
"
; blog2.Posts.Add(post1); blog2.Posts.Add(post2); blog2.Save(); tran.VoteCommit(); }
catch
(Exception ex) { MessageBox.Show(ex.Message
+
Environment.NewLine
+
ex.StackTrace); tran.VoteRollBack(); } } }

执行后数据库中EntityBase表的记录:

id  type    name     post_of          
1   blog   blog-1     NULL          
2   blog   Dotnet Fantasy   NULL
3   blog   blog-3     NULL          
4   blog   blog-4     NULL          
5   blog   blog-5     NULL          
6   post   post_01   2                  
7   post   post_02   2                  

 

结论:

  其实,这两种实现方法用“层”的概念来描述更贴切一些。
  至于用什么方式来实现所需要的继承,可以按需求来选择(当然不会仅限于这两种方法)。
  另外,不知道在NHibernate里处理继承关系是不是会更加灵活呢?

aggbug.aspx?PostID=1216
文章来源:

转载于:https://www.cnblogs.com/debug1/archive/2006/05/16/413757.html

你可能感兴趣的文章
SQLite移植手记1
查看>>
js05-DOM对象二
查看>>
mariadb BINLOG_FORMAT = STATEMENT 异常
查看>>
C3P0 WARN: Establishing SSL connection without server's identity verification is not recommended
查看>>
iPhone在日本最牛,在中国输得最慘
查看>>
动态方法决议 和 消息转发
查看>>
js 基础拓展
查看>>
C#生成随机数
查看>>
Android应用程序与SurfaceFlinger服务的连接过程分析
查看>>
Java回顾之多线程
查看>>
机电行业如何进行信息化建设
查看>>
9、总线
查看>>
Git 笔记 - section 1
查看>>
2018 Multi-University Training Contest 10 - Count
查看>>
HDU6203 ping ping ping
查看>>
《人人都是产品经理》书籍目录
查看>>
如何在git bash中运行mysql
查看>>
OO第三阶段总结
查看>>
构建之法阅读笔记02
查看>>
DataTable和 DataRow的 区别与联系
查看>>