链接到实体-三层架构

本文关键字:三层 实体 链接 | 更新日期: 2023-09-27 18:01:39

在过去的几个月里,我学到了很多关于链接到实体和带有DAO/DAL/Repository的三层体系结构的知识。现在有几件事一直困扰着我。我有三个问题,你将在下面看到。

有很多方法可以使存储库工作,但是什么方法是使存储库在性能方面工作的"最佳"方法呢?

1) 在构造函数

中初始化数据上下文
public class Repository : IRepository
{
    private Datacontext context;
    public Repository()
    {
        context = new Datacontext();
    }
    public IList<Entity> GetEntities()
    {
        return (from e in context.Entity
                select e).ToList();
    }
}

2) 使用"Using"

public class Repository : IRepository
{
    public IList<Entity> GetEntities()
    {
        using (Datacontext context = new Datacontext())
        {
            return (from e in context.Entity
                    select e).ToList();
        }
    }
}

3) 另一种方式(请注释)

我把你的建议放在这里,让别人评论


似乎有些人认为存储库应该向业务层返回一个IQueryable,而另一些人则认为最好返回一个illist。你对此有何看法?


上面第一个问题中的代码示例指向存储库,但是在业务层实现存储库的最佳方法是什么(在构造函数中初始化,使用"Using"??)

链接到实体-三层架构

我认为都可以。最主要的是,你应该让你的对象上下文相当短的寿命(IMHO)。因此,我认为你有两个选择:-

  1. 在单个方法调用中创建/销毁上下文,例如第二个示例中的using语句。

  2. 在创建/销毁存储库时创建/销毁上下文——在这种情况下,您的存储库应该实现IDisposable并将其本身包装在using语句中,并且应该是短寿命的。这种方法的好处是,您的存储库方法只需执行查询,而不会使用(new ObjectContext())污染方法;另一方面,责任转移到客户端来处理存储库。使用这种机制意味着您还可以在IQueryable<>中组合查询(前提是在处置存储库之前执行查询)。例如:

公共类Repository: IDisposable{DataHubContext context = new DataHubContext();

public IQueryable<Payment> GetPayments()
{
    return context.Payments;
}
public void Dispose()
{
    context.Dispose();
}

}

格式在SO中变得有点滑稽-对不起....然后在调用代码中:-

public class ClientCode
{
    public void DisplayPaymentsOnScreen()
    {
        Payment[] payments;
        using (var repository = new Repository())
        {
            payments = repository.GetPayments().Where(p => p.Amount > 100).ToArray();
        }
        // Do stuff with the data here...
    }
}

我认为这取决于你的需要…

如果您的存储库仅用于获取数据,那么我可能会使用Using技术,但说实话,您何时需要仅用于获取数据的存储库。你也会想要添加和更新,所以我肯定会去一个全局的数据上下文。这样做的好处是,您可以更新实体模型,然后保存更改。如果对每个调用使用不同的数据上下文,则无法持久化更改。

示例存储库应该是…

public class Repository : IRepository
{
private Datacontext context;
public Repository()
{
    context = new Datacontext();
}
public IList<Entity> GetEntities()
{
    return (from e in context.Entity
            select e).ToList();
}
public void Save()
{
    context.SubmitChanges();
}
}

…然后,您可以进行许多数据更改并一次提交到数据库。需要考虑的另一点是,在GetEntities中有一个ToList()调用。当你调用这个时,你实际上是在执行数据库查询。如果你打算对结果做进一步的逻辑处理,你可能想要返回一个IQueryable,只在你真正需要使用列表

时调用ToList。

我更喜欢using模式,因为它允许代码更干净和简单,因为我们知道db上下文的范围,并且可以清楚地知道它何时被处理,这在构造函数的情况下很难说。

另外,我不认为你可以在"使用"的情况下返回IQueryable作为db上下文将被处置一旦使用块退出,然后你不能在你的业务层使用返回的IQueryable

对于我自己,我总是返回IQueryable<T>

public IQueryable<Entity> GetEntities()
{
    return from e in context.Entity select e;
}

你必须阅读延迟执行http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx我使用它,所以我可以在业务逻辑或UI中查询实体的确切部分,而不是整个实体(像select *)

我倾向于在构造函数

中初始化上下文
public class Repository : IRepository
{
 private Datacontext context;
 public Repository()
 {
     context = new Datacontext();
 }
 public IQueryable<Entity> GetEntities()
 {
     return from e in context.Entity select e;
 }  
 public int Save()
 {
     // Return the number of the affected rows to determine in your code whether your query executed or not 
     return context.SubmitChanges();
 }

}

注意:另外,当您设计EF存储库时,请确保在所有存储库中都有上下文的一个实例,以避免在更新和删除期间出现错误。

我有一个通用的存储库,我在我的公司,我计划博客很快,它允许你只是容易地使CRUD操作,你可以扩展它,因为你想用很少的代码行。完成后,我会用URL

更新答案

如果您希望能够链接您的方法,以便进行最准确的查询,请使用第一种情况。如:

public class Repository : IRepository
{
    private Datacontext context;
    public Repository()
    {
        context = new Datacontext();
    }
    public IQueryabale<Entity> SelectAllEntities()
    {
         return context.Entity.Where(e=>! e.IsObsolote);
    }
    public IQueryable<Entity> SelectAllEntityRelatedToAnotherEntity(Entity otherEntity)
    {
         return this.SelectAllEntities().Where(e=>e.RelatedEntityId == otherEntity.Id);
    }
}

编辑
You can use it in collaboration with your business layer like this:
public class EntityManager()
{
     public IQueryable<Entities> FindAllApprovedEntities(Entity other)
     {
          return new Repository().SelectAllEntityRelatedToAnotherEntity(other).Where(e=>e.Approved);
     }
}