Какие ваши любимые способы инкапсулировать классы сущностей LINQ to SQL и классы контекста данных в бизнес-объекты?
Что вы нашли для работы в той или иной ситуации?
Вы изобрели какие-то особые узоры или привыкли к ним?
Какие ваши любимые способы инкапсулировать классы сущностей LINQ to SQL и классы контекста данных в бизнес-объекты?
Что вы нашли для работы в той или иной ситуации?
Вы изобрели какие-то особые узоры или привыкли к ним?
Я нашел шаблон, который, на мой взгляд, работает лучше всего - по крайней мере, в моем случае.
Я расширяю классы сущностей с помощью частичных классов. Я использую частичные классы, поэтому подпись объекта не меняется (см. Вызов DeleteOnSubmit в методе Delete).
Я приготовил небольшой пример. Вот изображение базы данных и настройки класса LINQ to SQL:

А вот частичный класс, в котором я реализую бизнес-логику:
/// <summary>
/// This class extends BusinessLogicDataContext.Products entity class
/// </summary>
public partial class Product
{
/// <summary>
/// New up a product by column: dbo.Products.ProductId in database
/// </summary>
public Product(Int32 id)
{
var dc = new BusinessLogicDataContext();
// query database for the product
var query = (
from p in dc.Products
where p.ProductId == id
select p
).FirstOrDefault();
// if database-entry does not exist in database, exit
if (query == null) return;
/* if product exists, populate self (this._ProductId and
this._ProductName are both auto-generated private
variables of the entity class which corresponds to the
auto-generated public properties: ProductId and ProductName) */
this._ProductId = query.ProductId;
this._ProductName = query.ProductName;
}
/// <summary>
/// Delete product
/// </summary>
public void Delete()
{
// if self is not poulated, exit
if (this._ProductId == 0) return;
var dc = new BusinessLogicDataContext();
// delete entry in database
dc.Products.DeleteOnSubmit(this);
dc.SubmitChanges();
// reset self (you could implement IDisposable here)
this._ProductId = 0;
this._ProductName = "";
}
}
Используя реализованную бизнес-логику:
// new up a product
var p = new Product(1); // p.ProductId: 1, p.ProductName: "A car"
// delete the product
p.Delete(); // p.ProductId: 0, p.ProductName: ""
Более того: классы сущностей LINQ to SQL очень открыты по своей природе. Это означает, что свойство, соответствующее столбцу dbo.Products.ProductId, реализует как средство получения, так и средство установки - это поле нельзя изменять.
Насколько мне известно, вы не можете переопределить свойства с помощью частичных классов, поэтому обычно я реализую менеджер, который сужает объект с помощью интерфейса:
public interface IProduct
{
Int32 ProductId { get; }
void Delete();
}
Я предпочитаю использовать шаблон Repository для инкапсуляции DataContexts.
Однако я хотел бы найти лучший способ генерировать объекты POCO из моего уровня данных при использовании LINQ2SQL.
Я только что опубликовал образец того, как вы можете структурировать свое приложение, которое использует Linq to Sql для хранения, используя шаблоны IoC и T4.
http://daniel.wertheim.se/2010/03/14/linq-to-sql-how-to-separate-the-entities-and-the-datacontext/
Прямо сейчас я пытаюсь использовать классы сущностей LINQ to SQL в качестве бизнес-объектов, чтобы передавать их между функциями и службами.
Конечно, у вас должны быть отдельные классы сущностей для доступа к базе данных, чтобы структура вашей базы данных могла изменяться без изменения бизнес-объектов!
Я тоже был бы очень заинтересован в хорошем решении для этого!
Ознакомьтесь с исходным кодом приложения MVC Sample, которое создает Роб Конери:
http://www.codeplex.com/mvcsamples/
У него есть отдельный слой сущностей, который сопоставляется с классами LINQ to SQL.
Я провел несколько экспериментов, используя Entity Framework и Linq to Entities, чтобы еще больше отделить мой клиентский код от базы данных, но мне показалось его неудобным в использовании, и я беспокоился о производительности.
В моем текущем проекте я использую Linq to SQL в качестве уровня данных, но у меня есть отдельные классы, в которых я реализую все запросы Linq. Классы возвращают сущности, определенные в моем контексте Linq to SQL, но запросы скрыты в методах.
Я нашел статьи от Иэн Купер на CodeBetter.com и серии Стивена Уолтера, бесценные для понимания необходимости чтобы сначала записать объекты POCO, а затем сопоставить их с базой данных, а не делать это наоборот (что я всегда делал).
Я обдумываю идею создания отдельного уровня модели объектно-ориентированного программирования (лучшая поддержка практик объектно-ориентированного программирования), но с использованием LINQ to SQL под капотом. Идея состоит в том, чтобы иметь XML-файл, который пользовательский инструмент будет использовать для генерации кода. Поскольку объекты LINQ to SQL слишком загромождены для моих предпочтений, я буду автоматически сгенерировать новые классы для использования в качестве своих объектов, и, конечно же, DataContext будет полностью скрыт для клиентского кода. Короткий ответ: создайте новые классы сущностей, но используйте базовые сущности LINQ to SQL и DataContext.