主要內容
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]
看一下ActiveRecord提供的空屬類型與實際類型對照表
public NullableDateTime CreatedDate
{
get { return _createdDate; }
set { _createdDate = value; }
}
[Property]
public NullableInt32 Count
{
get { return _count; }
set { _count = value; }
}
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等。