Clases de LINQ a SQL y contexto de datos: encapsulación de objetos de negocio

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

  •  03-07-2019
  •  | 
  •  

Pregunta

¿Cuáles son sus formas favoritas de encapsular las clases de entidad de LINQ to SQL y las clases de contexto de datos en objetos de negocio?

¿Qué has encontrado para trabajar en una situación dada?

¿Has inventado o llevado a algún patrón específico?

¿Fue útil?

Solución

He encontrado un patrón que creo que funciona mejor: en mi caso, al menos.


Extiendo clases de entidad usando clases parciales. Uso clases parciales para que la firma de la entidad no cambie (consulte la llamada DeleteOnSubmit en el método Delete ).

He cocinado un pequeño ejemplo. Aquí hay una imagen de la base de datos y la configuración de la clase LINQ to SQL:



Y aquí está la clase parcial en la que implemento la lógica de negocios:

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

Usando la lógica de negocio implementada:

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

Además: las clases de entidad LINQ to SQL son de naturaleza muy abierta. Esto significa que la propiedad correspondiente a la columna dbo.Products.ProductId implementa tanto un captador como un configurador; este campo no debe ser modificable.

Según mi conocimiento, no puede anular las propiedades usando clases parciales, por lo que lo que normalmente hago es implementar un administrador que reduzca el objeto mediante una interfaz:

public interface IProduct
{
    Int32 ProductId { get; }

    void Delete();
}

Otros consejos

Tiendo a usar el patrón Repository para encapsular DataContexts.

Patrón de repositorio

Me gustaría encontrar una mejor manera de emitir objetos POCO desde mi capa de datos mientras uso LINQ2SQL.

Acabo de publicar una muestra de cómo puedes estructurar tu aplicación que usa Linq to Sql para el almacenamiento, usando las plantillas IoC y T4.

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

En este momento, estoy tratando de usar las clases de entidad LINQ to SQL como objetos de negocio, para pasarlos entre funciones y servicios.

Por supuesto, debe tener clases de entidad separadas para el acceso a la base de datos , de modo que el diseño de su base de datos pueda cambiar sin cambiar los objetos de negocio.

¡Yo también estaría más interesado en una buena solución para esto!

Verifique el código fuente de la aplicación MVC Sample que está preparando Rob Conery:

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

Tiene una capa de entidad separada que se asigna a las clases de LINQ to SQL.

Hice algunos experimentos utilizando Entity Framework y Linq to Entities como una manera de separar aún más el código de mi cliente de la base de datos, pero me pareció torpe de usar y estaba preocupado por el rendimiento.

En mi proyecto actual, uso Linq to SQL como mi capa de datos, pero tengo clases separadas donde implemento todas las consultas de Linq. Las clases devuelven las entidades definidas en mi contexto de Linq a SQL, pero las consultas están ocultas en los métodos.

Encontré los artículos en Ian Cooper en CodeBetter.com y Stephen Walther serie inestimable en entendiendo la necesidad de escribir primero las entidades POCO y luego asignarlas a la base de datos en lugar de hacerlo al revés (que es lo que siempre solía hacer).

Estoy jugando con la idea de tener una capa separada del modelo OO (mejor soporte para las prácticas de OO), pero que use LINQ to SQL debajo del capó. La idea es tener un archivo xml que una herramienta personalizada utilizará para generar el código. Como las entidades de LINQ to SQL están demasiado saturadas para mis preferencias, generaré automáticamente nuevas clases para usarlas como mis entidades y, por supuesto, DataContext estará completamente oculto para el código del cliente. La respuesta corta es: crear nuevas clases de entidad, pero use las entidades LINQ a SQL subyacentes y DataContext.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top