Linq to sql LINQ到SQL实体和数据上下文类:业务对象封装

Linq to sql LINQ到SQL实体和数据上下文类:业务对象封装,linq-to-sql,c#-3.0,Linq To Sql,C# 3.0,您最喜欢用什么方式将LINQ到SQL实体类和数据上下文类封装到业务对象中 在特定的情况下,你发现什么是有效的 您是否发明或使用过任何特定的模式?现在,我正在尝试使用LINQ到SQL实体类作为业务对象,在函数和服务之间传递它们 当然,您应该为数据库访问提供独立的实体类,这样您的数据库布局就可以在不更改业务对象的情况下进行更改 我最感兴趣的是一个很好的解决方案 我使用Entity Framework和Linq to Entities做了一些实验,以进一步将我的客户机代码与数据库分开,但我发现使用起来

您最喜欢用什么方式将LINQ到SQL实体类和数据上下文类封装到业务对象中

在特定的情况下,你发现什么是有效的


您是否发明或使用过任何特定的模式?

现在,我正在尝试使用LINQ到SQL实体类作为业务对象,在函数和服务之间传递它们

当然,您应该为数据库访问提供独立的实体类,这样您的数据库布局就可以在不更改业务对象的情况下进行更改


我最感兴趣的是一个很好的解决方案

我使用Entity Framework和Linq to Entities做了一些实验,以进一步将我的客户机代码与数据库分开,但我发现使用起来很笨拙,而且担心性能


在我当前的项目中,我使用LINQtoSQL作为我的数据层,但有单独的类在其中实现所有Linq查询。这些类返回在我的Linq到SQL上下文中定义的实体,但查询隐藏在方法中

查看Rob Connery正在编写的MVC示例应用程序的源代码:


他有一个单独的实体层,映射到LINQ到SQL类。

我倾向于使用存储库模式来封装数据上下文


不过,我想找到一种更好的方法,在使用LINQ2SQL的同时从数据层发出POCO对象。

我发现和系列文章对于理解需要先编写POCO实体,然后将它们映射到数据库非常有价值,而不是反过来做(我一直都是这样做的).

我正在考虑一个单独的OO模型层(更好地支持OO实践),但它在幕后使用LINQ to SQL。其思想是拥有一个xml文件,自定义工具将使用该文件生成代码。 由于LINQ到SQL的实体对于我的首选项来说过于杂乱,我将自动生成新的类来用作我的实体,当然,对于客户端代码,DataContext将完全隐藏。
简单的回答是:创建新的实体类,但使用底层的LINQ to SQL实体和DataContext。

我发现了一种我认为最有效的模式——至少在我的情况下是这样。


我使用分部类扩展实体类。我使用分部类,因此实体的签名不会更改(请参见
Delete
方法中的
DeleteOnSubmit
调用)

我编了一个小例子。以下是数据库和LINQ to SQL类设置的图像:



下面是我实现业务逻辑的部分类:

/// <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到SQL实体类在本质上是非常开放的。这意味着对应于dbo.Products.ProductId列的属性实现了getter和setter——此字段不应该是可变的

据我所知,您不能使用分部类重写属性,因此我通常要做的是实现一个管理器,使用接口缩小对象范围:

public interface IProduct
{
    Int32 ProductId { get; }

    void Delete();
}

我刚刚发布了一个示例,介绍了如何使用IoC和T4模板构建使用Linq到Sql进行存储的应用程序