使用EntityFramework设计模式?

Ali*_*hşi 6 c# design-patterns entity-framework

接口

public interface IDinnerRepository 
{
    IQueryable<Dinner> FindAllDinners();
    IQueryable<Dinner> FindDinnersByText(string q);

    Dinner GetDinner(int id);

    void Add(Dinner dinner);
    void Delete(Dinner dinner);

    void Save();
}
Run Code Online (Sandbox Code Playgroud)

从上面的接口继承的类

public class DinnerRepository : NerdDinner.Models.IDinnerRepository
{
    NerdDinnerEntities db = new NerdDinnerEntities();

    Public IQueryable<Dinner> FindDinnersByText(string q)
    {
         return db.Dinners.Where(d => d.Title.Contains(q)
             || d.Description.Contains(q)
             || d.HostedBy.Contains(q));
    }

    public IQueryable<Dinner> FindAllDinners()
    {
         return db.Dinners;
    }

    public Dinner GetDinner(int id)
    {
        return db.Dinners.SingleOrDefault(d => d.DinnerID == id);
    }

    public void Add(Dinner dinner)
    {
        db.Dinners.AddObject(dinner);
    }

    public void Delete(Dinner dinner)
    {
        foreach (RSVP rsvp in dinner.RSVPs.ToList())
            db.RSVPs.DeleteObject(rsvp);

        db.Dinners.DeleteObject(dinner);
   }

   public void Save()
   {
        db.SaveChanges();
   }
}
Run Code Online (Sandbox Code Playgroud)

用于程序中

public class DinnerOperation
{
    DinnerRepository dr = new DinnerRepository();

    // insert
    public void InsertDinner()
    {
        Dinner dinner = dr.GetDinner(5);
        dr.Dinner.Add(dinner);
        dr.Save();
    }

    // delete
    public void DeleteDinner()
    {
        Dinner dinner = dr.GetDinner(5);
        dr.Dinner.Delete(dinner);
        dr.Save();
    }
}
Run Code Online (Sandbox Code Playgroud)

而且没有使用存储库设计模式......

public class DinnerOperation
{
    DinnerEntities entity = new DinnerEntities();

    // insert
    public void InsertDinner()
    {
        Dinner dinner = entity.Dinners.Find(5);
        entity.Dinner.Add(dinner);
        entity.SaveChanges();
    }

    // delete
    public void DeleteDinner()
    {
        Dinner dinner = entity.Dinners.Find(5);
        entity.Dinner.Remove(dinner);
        entity.SaveChanges();
    }
}
Run Code Online (Sandbox Code Playgroud)

我不明白,在这里,为什么我们使用设计模式?以这种方式使用具有实体框架的存储库设计模式并不意味着什么.

如何将设计模式与权利框架一起使用?什么时候使用实体框架的设计模式是有意义的?

Wik*_*hla 7

你几乎得到了它.首先,重构您的晚餐操作类,以便可以将存储库实现注入其中.

public class DinnerOperation
{
  private IDinnerRepository dr;
  public DinnerOperation( IDinnerRespository repository ) {
     this.dr = repository;
  }

  // insert
  public void InsertDinner()
  {
      Dinner dinner = dr.GetDinner(5);
      dr.Dinner.Add(dinner);
      dr.Save();
  }

  // delete
  public void DeleteDinner()
  {
      Dinner dinner = dr.GetDinner(5);
      dr.Dinner.Delete(dinner);
      dr.Save();
  }
}
Run Code Online (Sandbox Code Playgroud)

然后实现不同的存储库:

public class EntityFrameworkDinnerRepository : IDinnerRepository
public class NHibernateDinnerRepository : IDinnerRepository
public class Linq2SqlDinnerRepository : IDinnerRepository
public class MockDinnerRepository : IDinnerRepository
....
Run Code Online (Sandbox Code Playgroud)

然后使用您想要的任何存储库:

var repository = new ....Repository();
var operation = new DinnerOperation( repository );

operation.GetDinner(5);
Run Code Online (Sandbox Code Playgroud)

存储库用于抽象您的具体数据提供程序,从而使您的架构更加可靠.

想切换到nHibernate吗?

如果你到处都有EntityFramework,那就太痛苦了.很简单,如果您使用存储库,您只需注入另一个存储库,您的业务逻辑就不必更改.

想要对您的业务逻辑进行单元测试?

如果您坚持使用具体的数据提供商,那就太痛苦了.很简单,如果你有存储库,你只需要注入一个甚至不使用数据库的内存存储库.

现在明白了?


Kei*_*ith 6

我在使用ORM时拒绝使用存储库模式.我认为在这种情况下它几乎没有任何好处.(是的,我希望被狂热者投票约2000次).

使用EF,我为Context创建了一个界面

public interface IDinnerContext : IDisposable
{
    IDbSet<Dinner> Dinners;

    int SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

然后我将这个界面粘贴在我的EF DatabaseContext实现上,并且中提琴!我可以在任何地方使用EF,使用MOCK实现单元测试我的数据库访问,如果我愿意,可以使用注入,而不是最终使用600万个GetByXXX方法.IQeryable处理它,我得到延迟执行.我真的不需要插入/删除方法,因为IDBSet已经有添加/删除.我有更清晰/更容易阅读的代码,抽象更少.

如果我有一个案例,在许多不同的地方使用相同的查询,我真的希望这是常见的,那么我可以添加一些机制来支持它.但是,95%的情况下,查询特定于负责业务逻辑X的组件(简单GetBy语句之外的任何内容).所以我不认为这是一个问题.

不要误会我的意思,我虔诚地使用了存储库模式,直到ORM变得相当不错.一旦ORM达到一定程度的复杂程度,我觉得可能不再需要存储库模式,并且开始没有它的项目......并且永远不会回头看.我认为其他所有人最终都会朝这个方向发展,或者类似的东西,但旧的习惯会因此而死.(我知道一些仍然坚持使用锁(这个)的开发人员,因为它仍然在某些MS样本中).