2010-03-16 72 views
4

在过去的4年中,我一直在一家小公司工作,其中所有应用程序都是使用.NET 2.0中的智能UI反模式构建的。这意味着我对.NET 3.5和LINQ以及存储库和服务层等一般概念没有经验。我意识到为了找到一份新工作,我需要升级自己的知识,所以我已经开始阅读书籍,博客和许多SO问题,比如this one,现在是时候来尝试使用我应该有的东西做一个简单的应用学到了。关于Linq到SQL和存储库的困惑

我想构建一个小应用程序来管理项目中的错误。

这是非常基本的数据库关系图,我想出了:

The database http://www.kristofclaes.be/so/database.gif

我有翻译这个图如下类别(我省略了LINQ to SQL的属性):

class Project 
{ 
    public int ID { get; internal set; } 
    public string Name { get; set; } 
    public string Description { get; set; } 

    private EntitySet<Bug> bugs; 
    public EntitySet<Bug> Bugs 
    { 
     get { return this.bugs; } 
     set { this.bugs.Assign(value); } 
    } 
} 

class Bug 
{ 
    public int ID { get; internal set; } 
    public string Summary { get; set; } 
    public string Description { get; set; } 

    private EntityRef<Project> belongsTo; 
    public Project BelongsTo 
    { 
     get { return this.belongsTo.Entity; } 
     set { this.belongsTo.Entity = value; } 
    } 

    private EntityRef<Person> currentStatusSetBy; 
    public Person CurrentStatusSetBy 
    { 
     get { return this.currentStatusSetBy.Entity; } 
     set { this.currentStatusSetBy.Entity = value; } 
    } 

    public Datetime CurrentStatusSetOn { get; set; } 
    public BugStatus CurrentStatus { get; set; } 

    private EntitySet<BugStatusHistory> previousStatuses 
    public EntitySet<BugStatusHistory> PreviousStatuses 
    { 
     get { return this.previousStatuses; } 
     set { this.previousStatuses.Assign(value); } 
    } 
} 

class BugStatusHistory 
{ 
    public int ID { get; internal set; } 
    public DateTime StatusSetAt { get; set; } 
    public BugStatus Status { get; set; } 

    private EntityRef<Person> statusSetBy; 
    public Person StatusSetBy 
    { 
     get { return this.statusSetBy.Entity; } 
     set { this.statusSetBy.Entity = value; } 
    } 
} 

class Person 
{ 
    public ID { get; internal set; } 
    public string Name {get; set; } 
    public string Email { get; set; } 
    public string Login { get; set; } 
    public string Password { get; set; } 
} 

enum BugStatus { New, Confirmed, Solved } 

我已经把这些类叫做的DomainModel类库,我想引用的DomainModel从ASP.NET MVC 2应用程序。从我读过的内容中,我还应该添加存储库,甚至可以将服务层添加到我的DomainModel。这让我感到困惑。

我读过你不应该为每个类/表创建一个存储库,而是应该为聚合(类组)创建一个存储库。如果一个实体不能存在于另一个实体的上下文之外,它就不应该有它自己的存储库。在我的例子中,一个Bug总是与一个项目相关联。这是否意味着我应该为聚合的Project-Bug创建一个存储库?如果我想呈现所有错误的列表,无论它们在哪个项目中。我应该在我的IProjectsRepository中添加一个方法GetAllBugs()吗?还是应该为这种用法创建一个单独的IBugsRepository?

我认为创建单独的存储库可能在这里有它的优势。从我读过的关于Linq的SQL,你可以在DataContext上设置一个属性来指定如何处理懒惰和急切的加载。现在,当我列出项目或单个项目时,我想要加载Bug列表。但我不想急于将每个Bug的项目加载到该列表中。但是,如果我想加载所有错误的列表(无论项目)或一个错误,我想急切地加载的项目,但在这种情况下,我希望急切地加载该项目中的错误列表。我的LINQ到SQL knowlegde是非常有限的,但不是这个东西,只能通过设置DataContext的特性可以实现吗?那不是要求我有一个DataContext的项目和错误一个DataContext,因此两个储存?除非它能以某种方式告诉DataContext急切地加载2个级别,并对任何更深层次的内容进行延迟加载?或者是因为推迟执行这些都不相关?

请原谅我长期以来的问题(这可能甚至不是很清楚),但所有这些新信息都让我很困惑。

(你喜欢我的数据库图表/类结构发表评论我时,请不要吝惜我:-))

回答

2

我个人只使用存储库模式与L2S如果我将获得的替代方法存储在数据库中的数据 - 这通常意味着我也有一组用于Project,Bug等的接口。

存储库模式是一个L2S的球疼,因为它使复杂化更新 - 你从存储库中传出一个对象(打开并关闭DataContext来获取它 - 它应该是短暂的,你会看到),你修改它的属性并将其发送回来进行更新 - 但是你不能,因为你需要原始的DataContext。您需要再次从新的数据上下文中获取对象,复制修改的值并更新第二个。为避免这种情况,您必须开始将数据上下文传递到您的存储库中,以便执行大多数操作(让调用者确定数据上下文的生存期);这会膨胀你所有的方法签名,并且会导致a * s中的全面痛苦。

对于我来说,L2S的美妙之处在于它的速度 - 所以当我看到有人为了它而不必要地包装DC时,我不寒而栗。

不要误解我的意思 - 我正在写一个系统,此时每个对象和“数据服务”都被抽象到接口后面;并且其中一些数据服务是使用Linq To Sql实现的;但那是因为整个系统的目的是成为整个平台的热插拔后端。使用L2S一直很棘手,但它仍然可行。其次 - 根据您对急切和懒惰加载的担忧,您通常会使用DataLoadOptions class和DC实例的“LoadOptions”成员来控制此操作。

如果您发现需要对哪些内容进行懒惰和热切加载的细粒度控制,那么您不需要单独的DC - 只需将创建的datacontext卸载到针对不同需求量身定制的不同方法:

public MyDataContext GetDCForProjects() 
{ 
    var DC = new MyDataContext(); 
    DataLoadOptions dlo = new DataLoadOptions(); 
    dlo.LoadWith<Project>(p => p.Bugs); 
    DC.LoadOptions = dlo; 
    return DC; 
} 

//add more methods for the different needs