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

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

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

Вы придумали или приняли какие-либо конкретные шаблоны?

Ответы

Ответ 1

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



Я расширяю классы сущностей, используя частичные классы. Я использую частичные классы, поэтому подпись объекта не изменяется (см. Вызов DeleteOnSubmit в методе Delete).

Я приготовил небольшой пример. Здесь изображение базы данных и установки LINQ to SQL:

WqEHH.png

И вот частичный класс, в котором я реализую бизнес-логику:

/// <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, реализует как getter, так и setter - это поле не должно меняться.

Насколько я знаю, вы не можете переопределять свойства с помощью частичных классов, поэтому я обычно делаю это менеджер, который сужает объект с помощью интерфейса:

public interface IProduct
{
    Int32 ProductId { get; }

    void Delete();
}

Ответ 2

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

Образцовый шаблон

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

Ответ 4

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

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

Мне тоже было бы очень интересно получить хорошее решение!

Ответ 5

Проверьте исходный код приложения MVC Sample, которое собирает Rob Conery:

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

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

Ответ 6

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

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

Ответ 7

Я нашел статьи Ian Cooper на CodeBetter.com и Stephen Walther неоценимы в понимании необходимости сначала писать объекты POCO, а затем сопоставлять их с базой данных, а не делать это наоборот (это то, что я всегда делал).

Ответ 8

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