使用Linq将数据从UI代码分离到SQL实体

时间:2010-06-14 08:39:35

标签: linq-to-sql design-patterns

如果保持数据访问权限远离业务和表示层非常重要,我可以采取哪些替代方法或方法,以便我的LINQ to SQL实体可以保留在数据访问层中?

到目前为止,我似乎只是复制sqlmetal生成的类,并传递这些对象而只是为了保持两层appart。

例如,我的数据库中有一个名为Books的表。如果用户通过UI创建新书,则sqlmetal生成的Book类看起来非常合适,尽管我通过这种方式将我的设计紧密结合在一起。

2 个答案:

答案 0 :(得分:0)

我所做的是将所有DataAccess(在您的情况下为LINQ-to-SQL)放在一个项目中,然后我有另一个使用DataAccess项目的业务项目,从而将DataAccess项目从UI层集中。

在您的书籍示例中,我的业务层将有一个名为Book:

的类
public class Book
{

    private IAuthorRespository _authorRepository = new LinqToSqlAuthorRepository();
    private IBookRespository _bookRepository = new LinqToSqlBookRepository();

    public int BookId { get { return _bookId; }}
    private int _bookId;

    public virtual string BookName{get;set;}
    public virtual string ISBN {get;set;}
    // ...Other properties

    public Book()
    {
        // When creating a new book
        _bookId = 0;
    }

    public Book(int id)
    {
        // For an existing book
        _bookId = id;
        Load();
    }

    protected void Load()
    {
        BookEntity book = _bookRepository.GetBook(BookId);
        BookName = book.BookName;
        ISBN = book.ISBN;
    }

    public void Save()
    {
        BookEntity book = MapEntityFromThisClass();
        _bookRepository.Save(book);
    }

    public Author GetAuthor()
    {
        return _authorRepository.GetAuthor();
    }

}

这意味着您的UI与实际数据访问完全分离,并且所有Book逻辑都明确包含在类中。

您可以通过将IoC与Microsoft Unity或Castle等系统一起使用来进一步分离,这样您就不必编写= new LinqToSqlXYZ();,而是可以写IoC.Resolve<IBookRepostory>();的某些内容(取决于您的实施)。这意味着您的Book类不再受LINQ-to-SQL约束。

答案 1 :(得分:0)

Linq to Sql在实体和数据库表之间提供1:1映射。可以说,实体本身是远离数据库的抽象层次,这就是你所依赖的。

如果你将linq提供的实体1:1复制到sql,那么它可能意味着它不值得拥有它们,因为你仍然和那些类一样依赖于这些类由linq提供给sql。

通过创建另一个层,您还可以消除linq提供给sql的更改跟踪的好处,这意味着您必须将类中的任何更改复制到linq提供给sql的实体中以执行数据操作。

如果您想从任何表示层或业务层中抽象出DataContext类型代码,并更紧密地控制数据接口,那么存储库模式就是好的。您可以随时让您的存储库返回由linq创建的实体类型到sql,这意味着您不是复制类型,您也可以获得更改跟踪,但您仍然保留控制存储库中DataContext的代码。 / p>

您可以考虑将数据投影到不同的类中,以利于您的演示(视图模型)或业务逻辑。如果我想使用linq到sql,这是我倾向于走的路线,但我不希望实体和我的视图模型之间有1:1的映射。