Using Castle ActiveRecord with multiple databases

I <3 Castle ActiveRecord, but today I ran into something that I couldn't quite figure out.  The solution from the documentation was seemingly incorrect.  After much trial-and-error though, I have it figured out, and it turns out the docs were right, and I was wrong.  I'm documenting exactly what I did here in hopes that it might save someone else some pain someday.

The problem was that I needed to create ActiveRecord types that were backed by two different databases.  I'm not talking about a single type that pulls from both databases (not sure how that would work), I'm talking about a Foo coming from FooDatabase, and Bar coming from BarDatabase.  Checking the docs, it appears like all you need to do is create abstract base classes for each database, then derive your concrete types from them instead of from ActiveRecordBase.  So I tried that, setup my ActiveRecord.config file like it suggested, loaded the page, and EPIC FAIL.  Here's what I had:

   1: [ActiveRecord]
   2: public abstract class FooPersistable<T> : ActiveRecordBase<T>
   3: {
   4: }
   5:  
   6: ...
   7:  
   8: [ActiveRecord]
   9: public class BarPersistable<T> : ActiveRecordBase<T>
  10: {
  11: }

And here's what my config looked like:

   1: <activerecord isWeb="true" pluralizeTableNames="true">
   2:     <config>
   3:         <add key="connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
   4:         <add key="dialect" value="NHibernate.Dialect.MsSql2005Dialect" />
   5:         <add key="connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
   6:         <add key="connection.connection_string" value="Data Source=localhost; Initial Catalog=FooDatabase; Integrated Security=SSPI" />
   7:     </config>
   8:     <config type="Objects.BarPersistable`1, Objects">
   9:         <add key="connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
  10:         <add key="dialect" value="NHibernate.Dialect.MsSql2005Dialect" />
  11:         <add key="connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
  12:         <add key="connection.connection_string" value="Data Source=localhost; Initial Catalog=BarDatabase; Integrated Security=SSPI" />
  13:     </config>
  14: </activerecord>

Note that since BarPersistable is a generic type, it is specified using the class name suffixed with "`1".  That's very important.  The rest of the "type" attribute just tells ActiveRecord which assembly to look in for BarPersistable<>.  Also notice that the first <config> element doesn't specify a type; it's the "default" configuration.  Trying to specify a type there will cause ActiveRecord to become angry, so don't do it.

And for completeness, here's what my initialization code looked like:

   1: string configFile = HttpContext.Current.Server.MapPath("~/ActiveRecord.config");
   2:  
   3: ActiveRecordStarter.Initialize(
   4:     new XmlConfigurationSource(configFile), 
   5:     //Note the use of a generic type without a type parameter!
   6:     typeof(Foo),typeof(Bar),typeof(BarPersistable<>));

At this point, it maybe immediately obvious what I've done wrong, but I wrestled with it for about an hour before I saw it.  I forgot to mark BarPersistable as abstract.  That's it.  All I had to do was add that one minor keyword, and everything began to work beautifully, even with ASP.NET and the session-per-request model.  Very frustrating, but I have no one to blame but myself.  ActiveRecord even told me what to do in the error message, but I just assumed that there was no way I could have done something silly like left a keyword out.  Oops.

转载于:https://www.cnblogs.com/PeterHan/archive/2009/11/24/1609832.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值