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

StackOverflow https://stackoverflow.com/questions/223931

  •  03-07-2019
  •  | 
  •  

Вопрос

Каковы ваши любимые способы инкапсуляции классов сущностей 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 для 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, которое собирает Роб Конери:

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top