LINQ to SQL entity and data-context classes: business object encapsulation

Jakie są Twoje ulubione sposoby hermetyzacji klas encji LINQ do SQL i klas kontekstu danych w obiektach biznesowych?

Co znalazłeś do pracy w danej sytuacji?

Czy wymyśliłeś lub przyjąłeś jakieś konkretne wzory?

Author: cllpse , 2008-10-22

8 answers

Znalazłem wzór, który moim zdaniem działa najlepiej -- przynajmniej w moim przypadku.


Rozszerzam klasy encji za pomocą klas częściowych. Używam klas częściowych, aby sygnatura encji nie uległa zmianie (patrz wywołanie DeleteOnSubmit w metodzie Delete).

Przygotowałem mały przykład. Oto obraz bazy danych i konfiguracji klasy LINQ do SQL:



A oto część klasy, w której implementuję logikę biznesową:

/// <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 = "";
    }
}

Korzystanie z wdrożonego biznesu logika:

// 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: ""

Ponadto: klasy encji LINQ do SQL mają bardzo otwarty charakter. Oznacza to, że właściwość odpowiadająca dbo.Produkty.ProductId column implementuje zarówno getter jak i setter--to pole nie powinno być zmienne.

Według mojej wiedzy nie można nadpisać właściwości za pomocą klas częściowych, więc zazwyczaj robię to implementując menedżera, który zawęża obiekt za pomocą interfejsu:

public interface IProduct
{
    Int32 ProductId { get; }

    void Delete();
}
 3
Author: roosteronacid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-20 17:55:56

Używam wzorca repozytorium do hermetyzacji danych.

Wzór Repozytorium

Chciałbym znaleźć lepszy sposób na emitowanie obiektów POCO z mojej warstwy danych podczas korzystania z LINQ2SQL.

 2
Author: Zachary Yates,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-23 13:16:29

Właśnie opublikowałem próbkę tego, jak możesz uporządkować swoją aplikację, która używa Linq do Sql do przechowywania, używając IoC I T4-templates.

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

 2
Author: Daniel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-04 05:01:43

W tej chwili próbuję używać klas encji LINQ do SQL jako obiektów biznesowych, aby przekazywać je między funkcjami i usługami.

Oczywiście powinieneś mieć oddzielne klasy encji dla dostępu do bazy danych , aby układ bazy danych mógł się zmieniać bez zmiany obiektów biznesowych!

Ja też byłbym zainteresowany dobrym rozwiązaniem na to!

 1
Author: Sam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-22 08:50:52

Sprawdź kod źródłowy przykładowej aplikacji MVC, którą tworzy Rob Conery:

Http://www.codeplex.com/mvcsamples/

Posiada osobną warstwę encji, która mapuje do klas LINQ do SQL.

 1
Author: calebt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-22 21:41:55

Przeprowadziłem kilka eksperymentów przy użyciu Entity Framework i Linq do Entity jako sposób na dalsze oddzielenie kodu klienta od bazy danych, ale uznałem, że jest to niezręczne w użyciu i martwiłem się o wydajność.

W moim obecnym projekcie używam Linq do SQL jako warstwy danych, ale mam osobne klasy, w których implementuję wszystkie zapytania Linq. Klasy zwracają encje zdefiniowane w moim Linq do kontekstu SQL, ale zapytania są ukryte w metodach.

 0
Author: Rune Grimstad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-22 13:52:25

Znalazłem Artykuły Ian Cooper na CodeBetter.com I Seria Stephena Walthera nieoceniona w zrozumieniu potrzeby najpierw napisania encji POCO, a następnie mapowania ich do bazy danych, a nie robienia tego na odwrót (co zawsze robiłem).

 0
Author: Jeremy Holt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-23 21:28:19

Pogrywam sobie z pomysłem, aby mieć oddzielną warstwę modelu OO (lepsze wsparcie dla praktyk OO), ale które używają LINQ do SQL pod maską. Chodzi o to, aby mieć plik xml, którego niestandardowe narzędzie będzie używać do generowania kodu. Ponieważ LINQ do SQL entity są zbyt zaśmiecone dla moich preferencji, automatycznie wygeneruję nowe klasy do użycia jako moje encje i oczywiście DataContext będzie całkowicie ukryty dla kodu klienta. Czy krótka odpowiedź brzmi: Utwórz nowe klasy encji, ale użyj podstawy LINQ do encji SQL i DataContext.

 0
Author: Albert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-23 21:38:48