Entità LINQ to SQL e classi di contesto dei dati: incapsulamento di oggetti business

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

  •  03-07-2019
  •  | 
  •  

Domanda

Quali sono i tuoi modi preferiti per incapsulare le classi di entità LINQ to SQL e le classi di contesto dei dati in oggetti business?

Che cosa hai trovato per funzionare in una determinata situazione?

Hai inventato o adottato modelli specifici?

È stato utile?

Soluzione

Ho trovato un modello che penso funzioni meglio - nel mio caso, almeno.
Estendo le classi di entità usando classi parziali. Uso le classi parziali in modo che la firma dell'entità non cambi (vedi la chiamata DeleteOnSubmit nel metodo Delete ).

Ho preparato un piccolo esempio. Ecco un'immagine del database e della configurazione della classe LINQ to SQL:


Ed ecco la classe parziale in cui implemento la logica aziendale:

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

Utilizzo della logica aziendale implementata:

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

Inoltre: le classi di entità LINQ to SQL sono di natura molto aperta. Ciò significa che la proprietà corrispondente alla colonna dbo.Products.ProductId implementa sia un getter che un setter: questo campo non dovrebbe essere modificabile.

Per quanto ne so, non puoi sovrascrivere le proprietà usando le classi parziali, quindi quello che faccio di solito è implementare un gestore che restringe l'oggetto usando un'interfaccia:

public interface IProduct
{
    Int32 ProductId { get; }

    void Delete();
}

Altri suggerimenti

Tendo a utilizzare il modello di repository per incapsulare DataContexts.

Repository Pattern

Vorrei trovare un modo migliore per emettere oggetti POCO dal mio livello dati mentre utilizzo LINQ2SQL.

Ho appena pubblicato un esempio di come è possibile strutturare l'applicazione che utilizza Linq a SQL per l'archiviazione, utilizzando i modelli IoC e T4.

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

In questo momento sto cercando di utilizzare le classi di entità LINQ to SQL come oggetti business, per passarle tra funzioni e servizi.

Ovviamente, dovresti avere classi di entità separate per l'accesso al database , quindi il layout del tuo database può cambiare senza cambiare gli oggetti aziendali!

Sarei molto interessato anche a una buona soluzione anche per questo!

Scopri il codice sorgente per l'app di esempio MVC che Rob Conery sta mettendo insieme:

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

Ha un livello entità separato che si associa alle classi LINQ to SQL.

Ho fatto qualche sperimentazione usando Entity Framework e Linq to Entities come un modo per separare ulteriormente il mio codice cliente dal database, ma ho trovato goffo da usare ed ero preoccupato per le prestazioni.

Nel mio progetto attuale utilizzo Linq to SQL come livello dati, ma ho classi separate in cui implemento tutte le query Linq. Le classi restituiscono entità definite nel mio contesto Linq to SQL, ma le query sono nascoste nei metodi.

Ho trovato gli articoli di Ian Cooper su CodeBetter.com e Stephen Walther inestimabili in capire la necessità di scrivere prima le entità POCO e poi mapparle sul database invece di farlo al contrario (che è ciò che ho sempre usato fare).

Sto giocando con l'idea di avere un livello separato di modello OO (miglior supporto per le pratiche OO), ma che usano LINQ to SQL sotto il cofano. L'idea è di avere un file XML che uno strumento personalizzato utilizzerà per generare il codice. Poiché le entità LINQ to SQL sono troppo disordinate per le mie preferenze, genererò automaticamente nuove classi da utilizzare come entità personali e, naturalmente, DataContext sarà completamente nascosto per il codice client. La risposta breve è: creare nuove classi di entità ma utilizzare le entità LINQ to SQL e DataContext sottostanti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top