摘要:本文将会介绍使用ActiveRecord中的一些技巧。
主要内容
1.由实体类生成数据表
2.运行存在的SQL脚本
3.使用空属类型
4.使用枚举类型的属性
5.使用NHibernate中的日志记录
摘要:本文将会介绍使用ActiveRecord中的一些技巧。
主要内容
1.由实体类生成数据表
2.运行存在的SQL脚本
3.使用空属类型
4.使用枚举类型的属性
5.使用NHibernate中的日志记录
一.由实体类生成数据表
在前面所用到的例子中我们都是先有数据表结构,然后才有实体类,然而这会让很多朋友认为ORM怎么变成了ROM了,其实这只是我们平时的一个开发时的习惯问题,ActiveRecord是支持先有实体类,再由实体类生成数据库表。只不过我们可以在开发中根据项目的实际情况在这两种之间选择。看下面的代码,要生成数据库表结构,在实体类中需要多提供一些信息,是否为空,字段长度等。
[ActiveRecord("Blogs")]

public class Blog : ActiveRecordBase



{

private int _id;

private String _name;

private String _author;


[PrimaryKey(PrimaryKeyType.Native, "blog_id")]

public int Id


{


get
{ return _id; }


set
{ _id = value; }

}


[Property("blog_name", NotNull=true, Length=25)]

public String Name


{


get
{ return _name; }


set
{ _name = value; }

}


[Property("blog_author", NotNull=true, Length=50)]

public String Author


{


get
{ return _author; }


set
{ _author = value; }

}

}
要生成数据库表需要调用ActiveRecordStarter.CreateSchema()方法就可以了。
public void Initli()



{

XmlConfigurationSource source = new XmlConfigurationSource("MyConfig.xml");


ActiveRecordStarter.Initialize( source, typeof(Blog),typeof(Post),typeof(Custom));

ActiveRecordStarter.CreateSchema();

}
这里需要注意两点:
1.生成数据库表时只有当该表不存在时ActiveRecord才会生成,否则表如果存在ActiveRecord不会做任何事情,也不会报任何错误。
2.如果在实体类中没有指定字段的长度和是否为空,则默认生成的字段是允许为空的,且字符类生成后的字段类型为Nvarchar,长度为255。
二.运行存在的SQL脚本
有时候我们会想在ActiveRecord框架启动时运行一个已经存在的SQL脚本来生成数据库表结构,ActiveRecord同样也提供了这样的功能,通过调用ActiveRecordStarter.CreateSchemaFromFile()来实现。示例代码如下:
public void Initli()



{

XmlConfigurationSource source = new XmlConfigurationSource("MyConfig.xml");


ActiveRecordStarter.Initialize( source, typeof(Blog));


ActiveRecordStarter.CreateSchemaFromFile("MySqlScript.sql");

}
三.使用空属类型
在进行数据库操作时,有时候需要进行空值的处理,在ActiveRecord中给我们提供了一组空属类型,可以方便的进行处理,比如可以这样写属性:
[Property]

public NullableDateTime CreatedDate



{


get
{ return _createdDate; }


set
{ _createdDate = value; }

}


[Property]

public NullableInt32 Count



{


get
{ return _count; }


set
{ _count = value; }

}
看一下ActiveRecord提供的空属类型与实际类型对照表
CLR Basic Type
|
Nullable Type
|
System.Boolean
|
Nullables.NullableBoolean
|
System.Byte
|
Nullables.NullableByte
|
System.Char
|
Nullables.NullableChar
|
System.DateTime
|
Nullables.NullableDateTime
|
System.Decimal
|
Nullables.NullableDecimal
|
System.Double
|
Nullables.NullableDouble
|
System.Guid
|
Nullables.NullableGuid
|
System.Int16
|
Nullables.NullableInt16
|
System.Int32
|
Nullables.NullableInt32
|
System.Int64
|
Nullables.NullableInt64
|
System.SByte
|
Nullables.NullableSByte
|
System.Single
|
Nullables.NullableSingle
|
注意在使用空属类型时需要添加以下引用
Nullables.dll

Nullables.NHibernate.dll
四.使用枚举类型属性
在ActiveRecord中我们可以定义一个属性的类型为枚举类型,示例代码:
public class Post : ActiveRecordBase



{

//



private StatusType _status_type_id;


public enum StatusType


{

Editing = 0,

Published = 1,

Archived = 2

}


[Property("status_id")]

public StatusType Status


{


get
{ return _status_type_id; }


set
{ _status_type_id = value; }

}

}
在使用该实体类的StatusType属性时,可以这样赋值:
Post.Status = Post.StatusType.Archived;
五.使用NHibernate的日志记录
用过NHibernate的朋友都知道,NHibernate是用Log4net来记录日志的,在ActiveRecord中也可以通过简单的配置来使用Log4net记录。配置示例:
<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<configSections>

<section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />

<section name="activerecord" type="Castle.ActiveRecord.Framework.Config.ActiveRecordSectionHandler, Castle.ActiveRecord" />

<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />

</configSections>

<activerecord>

</activerecord>

<log4net>

<!-- Define some output appenders -->

<appener name="trace" type="log4net.Appender.TraceAppender, log4net">Õ

<layout type="log4net.Layout.PatternLayout,log4net">

<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] <%P{user}> - %m%n" />

</layout>

</appener>Õ

<appener name="console" type="log4net.Appender.ConsoleAppender, log4net">Õ

<layout type="log4net.Layout.PatternLayout,log4net">

<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] <%P{user}> - %m%n" />

</layout>

</appener>Õ

<appener name="rollingFile" type="log4net.Appender.RollingFileAppender,log4net">Õ

<param name="File" value="log.txt" />

<param name="AppendToFile" value="true" />

<param name="RollingStyle" value="Date" />

<param name="DatePattern" value="yyyy.MM.dd" />

<param name="StaticLogFileName" value="true" />

<layout type="log4net.Layout.PatternLayout,log4net">

<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] <%X{auth}> - %m%n" />

</layout>

</appener>Õ

<root>

<!-- priority value can be set to ALL|INFO|WARN|ERROR -->

<priority value="ALL" />

<appener-ref ref="rollingFile" />Õ

</root>

</log4net>

<nhibernate>

<!-- with this set to true, SQL statements will output to the console window if it's a console app -->

<add key="hibernate.show_sql" value="true" />

</nhibernate>

</configuration>
初始化配置在调用ActiveRecordStarter.Initialize()方法之前
public void Initli()



{

XmlConfigurationSource source = new XmlConfigurationSource("MyConfig.xml");

log4net.Config.XmlConfigurator.Configure();

ActiveRecordStarter.Initialize( source, typeof(Blog));

}
六.Hooks
有时候我们会在保存,加载,删除等操作时做一些必需的处理,这时可以通过重载以下三个方法来实现:
BeforeSave(IDictionary state)

BeforeLoad(IDictionary state)

BeforeDelete(IDictionary state)
比如说我们想在保存的时候设置Post的创建时间为当前时间,可以这样去写
protected override bool BeforeSave(IDictionary state)



{

state["Created"] = DateTime.Now;

return true;

}
本文就到这里了,同时本篇也是Castle ActiveRecord学习实践系列的最后一篇,过几天我会提供一个完整的ActiveRecord的例子程序。下面有时间我会继续写Castle中的其他部分,包括IOC及Facility,Aspect#,DynamicProxy等。
参考资料
文中很多内容来自于Castle的官方网站http://www.castleproject.org
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?