Entité LINQ to SQL et classes de contexte de données: encapsulation d'objet métier

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

  •  03-07-2019
  •  | 
  •  

Question

Quelles sont vos méthodes préférées pour encapsuler des classes d'entité LINQ to SQL et des classes de contexte de données dans des objets métier?

Qu'avez-vous trouvé efficace dans une situation donnée?

Avez-vous inventé ou adopté des modèles particuliers?

Était-ce utile?

La solution

J'ai trouvé un modèle qui, à mon avis, fonctionne le mieux - dans mon cas, du moins.


J'étends des classes d'entités en utilisant des classes partielles. J'utilise des classes partielles pour que la signature de l'entité ne change pas (voir l'appel DeleteOnSubmit dans la méthode Delete ).

J'ai préparé un petit exemple. Voici une image de la base de données et de la configuration de la classe LINQ to SQL:



Et voici la classe partielle dans laquelle j'implémente la logique métier:

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

Utilisation de la logique métier implémentée:

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

En outre: les classes d'entités LINQ to SQL sont de nature très ouverte. Cela signifie que la propriété correspondant à la colonne dbo.Products.ProductId implémente à la fois un getter et un setter - ce champ ne doit pas être modifiable.

À ma connaissance, vous ne pouvez pas remplacer les propriétés à l'aide de classes partielles. Par conséquent, ce que je fais habituellement est d'implémenter un gestionnaire qui rétrécit l'objet à l'aide d'une interface:

public interface IProduct
{
    Int32 ProductId { get; }

    void Delete();
}

Autres conseils

J'ai tendance à utiliser le modèle de référentiel pour encapsuler des DataContexts.

Modèle de référentiel

J'aimerais cependant trouver un meilleur moyen d'émettre des objets POCO à partir de ma couche de données tout en utilisant LINQ2SQL.

Je viens de publier un exemple de la façon dont vous pouvez structurer votre application en utilisant Linq à Sql pour le stockage, à l'aide d'IoC et de modèles T4.

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

À l'heure actuelle, j'essaie d'utiliser les classes d'entités LINQ to SQL en tant qu'objets métier pour les faire circuler entre les fonctions et les services.

Bien entendu, vous devez disposer de classes d'entités distinctes pour l'accès à la base de données . Ainsi, la présentation de votre base de données peut être modifiée sans modifier les objets métier!

Je serais très intéressé par une bonne solution pour cela aussi!

Découvrez le code source de l'application MVC Sample que Rob Conery est en train de rassembler:

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

Il possède une couche d'entité distincte qui correspond aux classes LINQ to SQL.

J'ai fait quelques expériences en utilisant Entity Framework et Linq to Entities afin de séparer davantage le code de mon client de la base de données, mais je trouvais que son utilisation était maladroite et je m'inquiétais des performances.

Dans mon projet actuel, j'utilise Linq to SQL en tant que couche de données, mais j'ai des classes séparées dans lesquelles j'implémente toutes les requêtes Linq. Les classes renvoient des entités définies dans mon contexte Linq to SQL, mais les requêtes sont masquées dans des méthodes.

J'ai trouvé les articles de Ian Cooper sur CodeBetter.com et les séries de Stephen Walther inestimables pour comprendre la nécessité d’écrire d’abord les entités POCO, puis de les mapper dans la base de données plutôt que de les faire à l’inverse (ce que j’ai toujours fait).

Je joue avec l'idée de disposer d'une couche distincte de modèle OO (meilleure prise en charge des pratiques OO), mais qui utilise LINQ to SQL sous le capot. L'idée est de disposer d'un fichier XML qu'un outil personnalisé utilisera pour générer le code. Étant donné que les entités LINQ to SQL sont trop encombrées pour mes préférences, je générerai automatiquement de nouvelles classes à utiliser comme entités et, bien entendu, le DataContext sera complètement masqué pour le code client. La réponse courte est: Créez de nouvelles classes d’entités, mais utilisez les entités LINQ to SQL sous-jacentes et DataContext.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top