如果让数据访问远离业务层和表示层非常重要,那么我可以采取哪些替代方法或方法,以便我的LINQ to SQL实体可以保留在数据访问层?从LINQ到SQL实体的UI代码中分离数据
到目前为止,我似乎只是简单地复制sqlmetal生成的类,并传递这些对象,而不是简单地保留两个appart。
例如,我在我的数据库中有一张名为Books的表格。如果用户通过UI创建新书,由sqlmetal生成的Book类看起来像是一个完美的适合,尽管我通过这样做来紧密耦合我的设计。
如果让数据访问远离业务层和表示层非常重要,那么我可以采取哪些替代方法或方法,以便我的LINQ to SQL实体可以保留在数据访问层?从LINQ到SQL实体的UI代码中分离数据
到目前为止,我似乎只是简单地复制sqlmetal生成的类,并传递这些对象,而不是简单地保留两个appart。
例如,我在我的数据库中有一张名为Books的表格。如果用户通过UI创建新书,由sqlmetal生成的Book类看起来像是一个完美的适合,尽管我通过这样做来紧密耦合我的设计。
我所做的是在一个项目中使用我的所有DataAccess(您的案例中的LINQ到SQL),然后我有另一个使用DataAccess项目的业务项目,从而将DataAccess项目从UI层分割开来。
在你的榜样的书籍,我的业务层将有一类称为书:
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完全从实际的数据访问分离,您的所有图书的逻辑包含明智地在一个班级内。
您可以使用IoC与Microsoft Unity或Castle等系统进行进一步分离,以便您不必编写= new LinqToSqlXYZ();
,而是可以按照IoC.Resolve<IBookRepostory>();
(取决于您的实现)的方式写东西。这意味着您的Book类不再与LINQ to SQL绑定。
Linq to Sql提供实体和数据库表之间的1:1映射。有人可能会认为,实体本身是远离数据库的抽象级别,这就是你被绑定到的东西。
如果你将linq提供给sql的实体进行1:1的重复,那么这可能意味着它不值得让它们在那里,因为你仍然与这些类绑定在一起,就像你一样由linq提供给sql的实体。
通过创建另一个图层,您还可以将linq提供给sql的更改跟踪的优势降低,这意味着您必须将您类中的任何更改复制到由linq提供给sql的实体中以执行数据操作。
如果您想要从任何演示文稿或业务层抽象出DataContext
类型代码,并更紧密地控制数据的接口,那么存储库模式是很好的。您始终可以让您的存储库将由linq创建的实体类型返回给sql,这意味着您不会复制类型,也可以获取更改跟踪,但是您仍然保存控制存储库内DataContext
的代码。
为了演示文稿(视图模型)或业务逻辑的好处,您可能会考虑将数据投影到不同的类中。这是我倾向于下去的路线,如果我想使用linq到sql,但我不想在实体和我的视图模型之间进行1:1映射。