Сущность LINQ to SQL и классы контекста данных: инкапсуляция бизнес-объектов

Какие ваши любимые способы инкапсулировать классы сущностей LINQ to SQL и классы контекста данных в бизнес-объекты?

Что вы нашли для работы в той или иной ситуации?

Вы изобрели какие-то особые узоры или привыкли к ним?


person Community    schedule 21.10.2008    source источник


Ответы (8)


Я нашел шаблон, который, на мой взгляд, работает лучше всего - по крайней мере, в моем случае.


Я расширяю классы сущностей с помощью частичных классов. Я использую частичные классы, поэтому подпись объекта не меняется (см. Вызов 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();
}
person Community    schedule 29.09.2009

Я предпочитаю использовать шаблон Repository для инкапсуляции DataContexts.

Шаблон репозитория

Однако я хотел бы найти лучший способ генерировать объекты POCO из моего уровня данных при использовании LINQ2SQL.

person Community    schedule 23.10.2008

Я только что опубликовал образец того, как вы можете структурировать свое приложение, которое использует Linq to Sql для хранения, используя шаблоны IoC и T4.

http://daniel.wertheim.se/2010/03/14/linq-to-sql-how-to-separate-the-entities-and-the-datacontext/

person Community    schedule 14.03.2010

Прямо сейчас я пытаюсь использовать классы сущностей LINQ to SQL в качестве бизнес-объектов, чтобы передавать их между функциями и службами.

Конечно, у вас должны быть отдельные классы сущностей для доступа к базе данных, чтобы структура вашей базы данных могла изменяться без изменения бизнес-объектов!

Я тоже был бы очень заинтересован в хорошем решении для этого!

person Community    schedule 22.10.2008

Ознакомьтесь с исходным кодом приложения MVC Sample, которое создает Роб Конери:

http://www.codeplex.com/mvcsamples/

У него есть отдельный слой сущностей, который сопоставляется с классами LINQ to SQL.

person Community    schedule 22.10.2008

Я провел несколько экспериментов, используя Entity Framework и Linq to Entities, чтобы еще больше отделить мой клиентский код от базы данных, но мне показалось его неудобным в использовании, и я беспокоился о производительности.

В моем текущем проекте я использую Linq to SQL в качестве уровня данных, но у меня есть отдельные классы, в которых я реализую все запросы Linq. Классы возвращают сущности, определенные в моем контексте Linq to SQL, но запросы скрыты в методах.

person Community    schedule 22.10.2008

Я нашел статьи от Иэн Купер на CodeBetter.com и серии Стивена Уолтера, бесценные для понимания необходимости чтобы сначала записать объекты POCO, а затем сопоставить их с базой данных, а не делать это наоборот (что я всегда делал).

person Community    schedule 23.10.2008

Я обдумываю идею создания отдельного уровня модели объектно-ориентированного программирования (лучшая поддержка практик объектно-ориентированного программирования), но с использованием LINQ to SQL под капотом. Идея состоит в том, чтобы иметь XML-файл, который пользовательский инструмент будет использовать для генерации кода. Поскольку объекты LINQ to SQL слишком загромождены для моих предпочтений, я буду автоматически сгенерировать новые классы для использования в качестве своих объектов, и, конечно же, DataContext будет полностью скрыт для клиентского кода. Короткий ответ: создайте новые классы сущностей, но используйте базовые сущности LINQ to SQL и DataContext.

person Community    schedule 23.10.2008