На этот раз мы подойдем к мэппингу POCO объектов несколько с другой стороны. Бывают ситуации, когда вы не должны использовать ORM по тем или иным причинам, например — пожелание заказчика или какие то другие факторы (например, разработка для мобильных устройств).
Что делать в этом случае? Остается один лишь ADO .NET с нашими любимыми DbCommand и DbConnection.
А вот и есть выход! Легковесная библиотека, позволяющая использовать некоторые преимущества ORM мэппинга без использования непосредственно ORM.
Имя ей — Fluent Ado.NET. Знакомьтесь!
Официальная страничка этого чуда на Codeplex: fluentado.codeplex.com
Исходный код можно взять здесь через SVN: FluentAdo.svn.codeplex.com/svn
Компилим скачанные исходники. Если при компиляции возникнут ошибки — советую удалть из солюшена ссылки на проекты тестов и сделать ребилд снова.
Что мы имеем внутри солюшена? Четыре проекта:
* FluentAdo.Generic
* FluentAdo.Oledb
* FluentAdo.Oracle
* FluentAdo.SQLite
Мне по нраву пришелся первый 🙂
По большому счету в исходниках написаны шаблоны, которые вы без труда сможете продублировать в своем основном проекте. Однако есть возможность использовать ссылку готовую библиотеку, подключив к проекту. Ниже мы рассмотрим второй вариант.
Весь синтаксис SQL будет отныне находиться под вашим бдительным взором, вы не должны пропустить ни единого поля. Чаще всего вы будете иметь дело с классом FluentCommand<>, который выполняет SQL запрос и производит мэппинг результатов. Команде нужно будет указать явно соединение примерно так:
SqlConnection myConnection = new SqlConnection(myConnectionString); FluentCommandcmd = new FluentCommand (); cmd.SetConnection(myConnection);
Классы из DAL останутся теми же (POCO):
public class Product { public string Code { get; set; } public int ProductNumber { get; set; } public string Name { get; set; } public double Price { get; set; } } public class Order { public int OrderNumber { get; set; } public string Comment { get; set; } public DateTime Date { get; set; } public int Count { get; set; } public Customer Customer { get; set; } public Product Product { get; set; } }
А чтобы осуществить выборку из базы (конечно, база должна быть создана), нужно написать следующее:
public static Product GetProductByNumber(int number) { SqlConnection myConnection = GetSqlConnection(); string sql = "select Code, ProductNumber, Name, Price from Product where ProductNumber = @ProductNumber"; return new FluentCommand(sql) .SetConnection(myConnection) .AddInt("ProductNumber", number) .SetMap(x => new Product { Code = x.GetString("Code"), Name = x.GetString("Name"), ProductNumber = x.GetInt("ProductNumber"), Price = x.GetValue ("Price"), }) .AsSingle(); } public static List GetProductList() { SqlConnection myConnection = GetSqlConnection(); string sql = "select Code, ProductNumber, Name, Price from Product"; return new FluentCommand (sql) .SetConnection(myConnection) .SetMap(x => new Product { Code = x.GetString("Code"), Name = x.GetString("Name"), ProductNumber = x.GetInt("ProductNumber"), Price = x.GetValue ("Price"), }) .AsList(); }
Здесь мы опустили GetSqlConnection, потому что он это к делу не относится 😉
Есть еще много над чем подумать, например, каскадная загрузка таблиц (Product <-> Order), как мы делали это при использовании Fluent NHibernate.
Но в общем и целом технология очень удобна, и, если вы не хотите использовать ничего тяжеловесного, а наоборот, хотите получить полный контроль над Sql-командами, выполнением запросов и тп., то FluentAdo .NET — для вас.