понедельник, 12 апреля 2010 г.

Castle ActiveRecord - какая красота!

Castle ActiveRecord - какая красота!

В последнее время я все гляжу в сторону Castle Project. Наконец, дошли руки поиграться с ActiveRecord.

Говорят, что термин ActiveRecord придумал вездесущий Фаулер. Этот паттерн используется в Ruby on Rails и в других MVC-каркасах. Подробности можно поискать в гугле.

Castle Project предлагает на безвозмездной основе реализацию ActiveRecord, которая вызвала у меня восторг.

Чтобы попытаться придти в такой же восторг, попробуйте такое:

  1. Скачайте ActiveRecord и распакуйте куда вам удобно
  2. Создайте Console Application в VS 2008 и добавьте ссылки на сборки:

    Castle.ActiveRecord
    Castle.ActiveRecord.Linq
    Castle.Core
    NHibernate
    NHibernate.ByteCode.Castle
    NHibernate.Linq
    System.Data.SQLite

  3. В Program.cs поместите такой код:
// A domain object:

[ActiveRecord]
public class Developer : ActiveRecordLinqBase<Developer> {

[PrimaryKey]
public int ID { get; private set; }

[Property]
public string Name { get; set; }

[Property]
public double CoffePerDay { get; set; }

}

// An app:

class Program {
static void Main(string[] args) {

// Configuring NHibernate
// I wish Fluent NHibernate worked with ActiveRecord
// But unfortunately in general it doesn't:
// http://stackoverflow.com/questions/1915454/using-castle-activerecord-with-fluent-nhibernate/1918929#1918929

var props = new Dictionary<string, string>() {
{ "connection.driver_class", typeof(NHibernate.Driver.SQLite20Driver).AssemblyQualifiedName },
{ "dialect", typeof(NHibernate.Dialect.SQLiteDialect).AssemblyQualifiedName },
{ "connection.provider", typeof(NHibernate.Connection.DriverConnectionProvider).AssemblyQualifiedName },
{ "connection.connection_string", "Data Source=c:/test.db" },
{ "proxyfactory.factory_class", typeof(NHibernate.ByteCode.Castle.ProxyFactoryFactory).AssemblyQualifiedName },
{ "show_sql", "true"}
};

// Initializing ActiveRecord

var source = new InPlaceConfigurationSource();
source.Add(typeof(ActiveRecordBase), props);
ActiveRecordStarter.Initialize(Assembly.GetExecutingAssembly(), source);
ActiveRecordStarter.UpdateSchema();

// Application logic:

if(Developer.Queryable.Count() < 1) {
using(new SessionScope()) {
new Developer() { Name = "Lexa", CoffePerDay = 0.1 }.Create();
new Developer() { Name = "SergeS", CoffePerDay = 1.5 }.Create();
new Developer() { Name = "Ramon", CoffePerDay = 0 }.Create();
new Developer() { Name = "Beresta", CoffePerDay = 1 }.Create();
}
}

var report = from i in Developer.Queryable
orderby i.CoffePerDay
where i.CoffePerDay > 0
select new { Name = i.Name };

foreach(var item in report)
Console.WriteLine(item);

Console.ReadKey();
}
}

После первого запуска в консоль будет выведено:

NHibernate: SELECT count(*) as y0_ FROM Developer this_
NHibernate: INSERT INTO Developer (Name, CoffePerDay) VALUES (@p0, @p1); select last_insert_rowid();@p0 = 'Lexa', @p1 = 0,1
NHibernate: INSERT INTO Developer (Name, CoffePerDay) VALUES (@p0, @p1); select last_insert_rowid();@p0 = 'SergeS', @p1 = 1,5
NHibernate: INSERT INTO Developer (Name, CoffePerDay) VALUES (@p0, @p1); select last_insert_rowid();@p0 = 'Ramon', @p1 = 0
NHibernate: INSERT INTO Developer (Name, CoffePerDay) VALUES (@p0, @p1); select last_insert_rowid();@p0 = 'Beresta', @p1 = 1
NHibernate: SELECT this_.Name as y0_ FROM Developer this_ WHERE this_.CoffePerDay > @p0 ORDER BY this_.CoffePerDay asc;@p0 = 0
{ Name = Lexa }
{ Name = Beresta }
{ Name = SergeS }

Выводится это потому, что в настройках присутствовал параметр show_sql.

Видно, что:

  • Проектирование идет от объектов
  • Работа ведется с объектами
  • Не нужно никаких маппингов
  • Для хранения можно использовать любую базу из тех, что поддерживает NHibernate
  • LINQ работает!

Wow I like it.

Комментариев нет:

Отправить комментарий