Linq to sql 对LINQtoSQL和存储库感到困惑

Linq to sql 对LINQtoSQL和存储库感到困惑,linq-to-sql,repository-pattern,Linq To Sql,Repository Pattern,在过去的4年中,我一直在一家小公司担任ASP.NET开发人员,该公司的所有应用程序都是使用.NET 2.0中的智能UI反模式构建的。这意味着我没有使用.NET3.5和LINQ之类的东西以及存储库和服务层之类的一般概念的经验。我意识到为了找到一份新的工作,我需要提升我的知识,所以我开始阅读书籍、博客和很多类似的问题,现在是时候尝试用我应该学到的知识做一个简单的应用了 我想构建一个小应用程序来管理项目中的bug 这是我提出的最基本的数据库图: (来源:) 我已将此图转换为以下类(省略了Linq t

在过去的4年中,我一直在一家小公司担任ASP.NET开发人员,该公司的所有应用程序都是使用.NET 2.0中的智能UI反模式构建的。这意味着我没有使用.NET3.5和LINQ之类的东西以及存储库和服务层之类的一般概念的经验。我意识到为了找到一份新的工作,我需要提升我的知识,所以我开始阅读书籍、博客和很多类似的问题,现在是时候尝试用我应该学到的知识做一个简单的应用了

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

这是我提出的最基本的数据库图:


(来源:)

我已将此图转换为以下类(省略了Linq to SQL属性):

类项目
{
公共整数ID{get;内部集合;}
公共字符串名称{get;set;}
公共字符串说明{get;set;}
私有实体集bug;
公共实体集错误
{
获取{返回this.bugs;}
设置{this.bugs.Assign(value);}
}
}
类错误
{
公共整数ID{get;内部集合;}
公共字符串摘要{get;set;}
公共字符串说明{get;set;}
私人实体REF属于私人实体;
公共项目属于
{
获取{返回this.belongsTo.Entity;}
设置{this.belongsTo.Entity=value;}
}
私有实体ref currentStatusSetBy;
公众人物
{
获取{返回this.currentStatusSetBy.Entity;}
设置{this.currentStatusSetBy.Entity=value;}
}
公共日期时间CurrentStatusSetOn{get;set;}
公共BugStatus CurrentStatus{get;set;}
私有实体设置以前的状态
公共实体设置以前的状态
{
获取{返回this.previousStatuses;}
设置{this.previousStatuses.Assign(value);}
}
}
类历史记录
{
公共整数ID{get;内部集合;}
public DateTime StatusSetAt{get;set;}
公共BugStatus状态{get;set;}
私人实体REF状态设置;
公众人物身份
{
获取{返回this.statusSetBy.Entity;}
设置{this.statusSetBy.Entity=value;}
}
}
班主任
{
公共ID{get;内部集合;}
公共字符串名称{get;set;}
公共字符串电子邮件{get;set;}
公共字符串登录{get;set;}
公共字符串密码{get;set;}
}
枚举错误状态{新建,已确认,已解决}
我将这些类放在一个名为DomainModel的类库中,我想从ASP.NET MVC 2应用程序中引用该DomainModel。根据我所读的内容,我还应该向我的DomainModel中添加存储库,甚至一个服务层。这就是让我困惑的地方

我已经读到,您不应该为每个类/表创建一个存储库,而应该为聚合(类组)创建一个存储库。如果一个实体不能脱离另一个实体的上下文而存在,它就不应该有自己的存储库。在我的例子中,一个Bug总是链接到一个项目。这是否意味着我应该为聚合项目Bug创建一个存储库?如果我想呈现所有bug的列表,不管它们在哪个项目中,该怎么办。我应该向我的IProjectsRepository添加一个方法GetAllBugs()?或者我应该为该用途创建一个单独的IBugsRepository吗

我认为在这里创建单独的存储库可能有它的优势。从我所读到的关于Linq to SQL的内容来看,您可以在DataContext上设置一个属性来指定如何处理延迟和急切加载。现在,当我得到一个项目列表或单个项目时,我想急切地加载bug列表。但我不想急于加载列表中每个Bug的项目。但是,如果我想加载所有Bug的列表(无论项目如何)或单个Bug,我确实希望加载该项目,但在这种情况下,我不希望加载该项目中的Bug列表。我的Linq到SQL Knowledge非常有限,但这不是只有通过设置DataContext属性才能实现的吗?这难道不需要我有一个用于项目的DataContext和一个用于bug的DataContext,以及两个存储库吗?除非有可能告诉DataContext急切地加载到2个级别,并对更深层的内容进行延迟加载?还是所有这些都因为延迟执行而无关紧要

请原谅我提出了一个很长很长的问题(可能还不太清楚),但所有这些新信息真的让我困惑


(如果你想评论我的数据库图/类结构,请不要吝惜我:-)

我个人只在L2S中使用存储库模式,如果我有其他方法来获取存储在数据库中的数据-这通常意味着我还有一组用于项目、Bug等的接口

存储库模式对于L2S来说是一个很复杂的问题,因为它会使更新复杂化——你从存储库中传递一个对象(打开和关闭一个DataContext来获取它——你看,它们应该是短暂的),你修改它的属性并将其发送回以进行更新——但是你不能,因为你需要原始的DataContext。您需要再次从新的数据上下文中获取对象,复制修改后的值,然后更新第二个值

为了避免这种情况,对于大多数操作,您必须开始将数据上下文传递到存储库中(让调用方确定数据上下文的生存期);这会膨胀你所有的方法签名,并在a*s中造成全面的痛苦

对我来说,L2S的美妙之处在于它的速度——因此,当我看到人们为了它而不必要地包装DC时,我不寒而栗

别误会,我现在正在编写一个系统,每个对象和“数据服务”都被抽象到接口后面;其中一些数据服务是使用Linq到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 }
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