Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用EntityFramework设计模式?_C#_Entity Framework_Design Patterns - Fatal编程技术网

C# 使用EntityFramework设计模式?

C# 使用EntityFramework设计模式?,c#,entity-framework,design-patterns,C#,Entity Framework,Design Patterns,接口 public interface IDinnerRepository { IQueryable<Dinner> FindAllDinners(); IQueryable<Dinner> FindDinnersByText(string q); Dinner GetDinner(int id); void Add(Dinner dinner); void Delete(Dinner dinner); void S

接口

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();
}
而且不使用存储库设计模式

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();
    }
}
问题:

我不明白,在这里,我们为什么要使用设计模式? 以这种方式将存储库设计模式与实体框架结合使用并不意味着什么


如何将设计模式与entitiy framework结合使用?什么时候将设计模式与实体框架结合使用才有意义?

这是存储库模式,它本身就是实体框架的超级模式,因为
DbContext
同时充当存储库和工作单元,但它是不可模仿的-没有
IDbContext
。因此,您最终将
DbContext
放在一个精简的存储库包装器中,以便以后可以轻松地测试组件

我认为值得一提的是,我从未在NHibernate中使用过存储库模式,因为会话和会话工厂是接口-
ISession
ISessionFactory

如果您在某处(
IRepository
)按接口使用存储库并将其注入,则通过模拟/存根进行测试将更容易:

public class DinnerOperation
{
    private readonly IDinnerRepository repository;

    public DinnerOperation(IDinnerRepository dinnerRepository)
    {
        repository = dinnerRepository;
    }
}
当然,您必须使用所选的IoC容器为您注入正确的实例(
DinnerRepository
,在本例中),或者手动执行DI


这样,您就可以针对模拟或存根存储库测试
dinnerooperation
类。当您实例化
DbContext
时,您不能这样做。

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

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();
  }
}
然后实现不同的存储库:

public class EntityFrameworkDinnerRepository : IDinnerRepository
public class NHibernateDinnerRepository : IDinnerRepository
public class Linq2SqlDinnerRepository : IDinnerRepository
public class MockDinnerRepository : IDinnerRepository
....
然后使用您想要的任何存储库:

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

operation.GetDinner(5);
存储库用于抽象您的具体数据提供者,从而使您的体系结构更加合适

想换成nHibernate吗

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

想要单元测试您的业务逻辑吗

如果你坚持使用一个具体的数据提供者,那会很痛苦。 很简单,如果您有存储库,只需注入一个inmemory存储库,它甚至不使用数据库


现在明白了吗?

当我使用ORM时,我拒绝使用存储库模式。我认为在这种情况下,它几乎没有什么好处。(是的,我预计会被狂热者投下2000票)

使用EF,我为我的上下文创建了一个接口

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

    int SaveChanges();
}
公共接口IDinerContext:IDisposable
{
套餐;
int SaveChanges();
}
然后,我将这个接口粘贴在我的EF DatabaseContext实现上,还有viola!我可以在任何地方使用EF,通过模拟实现对我的db访问进行单元测试,如果我愿意,可以使用注入,而不是使用600万个GetByXXX方法。IQeryable处理了,我的执行被延迟了。我并不真正需要Insert/Delete方法,因为IDBSet已经有了Add/Remove。我的代码更清晰/更容易阅读,抽象更少

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


别误会,在ORMs变得相当不错之前,我一直虔诚地使用存储库模式。一旦ORMs达到了一定的成熟度,我觉得可能不再需要存储库模式,于是开始在没有它的情况下进行项目。。。。而且从未回头。我认为其他所有人最终都会朝着这个方向走,或者类似的方向走,但旧习惯的消亡需要一段时间。(我知道一些开发人员仍然坚持使用锁(这个),因为它仍然存在于一些MS示例中)。

非常感谢。有很多东西要学:)。是否有任何教程、文章等。。。关于这个话题。我差点就明白了。为了更好地理解,你有什么建议吗?我不记得有任何简明而完整的资料来源。只需在“Repository pattern explained”上用谷歌搜索一下,再多读几篇教程,研究一下与Repository模式配合得很好的依赖注入模式。从EF切换到NH或内存中的提供者或其他任何东西都不“容易”使用一个公开
IQueryable
@Slauma的存储库:这非常简单,因为类库包含IEnumerables上的AsQueryable扩展方法。NH还支持linq。我为linq2sql、nhibernate、ef、xpo和内存实现了存储库,它们都实现了相同的接口。是的,NH支持LINQ,但与ef(LINQ到实体)不同,LINQ到实体不是LINQ到对象,也不是LINQ到SQL。您可以使用相同的LINQ代码,所有代码都可以编译,但一个可以工作,另一个不能工作,或者其行为不同。它依赖于提供程序,如果使用提供程序2的代码正常工作,则无法使用使用提供程序1的代码进行测试。这里更好地解释了我的意思:(包括答案末尾的链接)。+1。另一种观点。在你回答之后,我有点困惑。我认为,在决定使用哪一种时,需要经验。这给了我继续编码的士气。非常感谢……嗯,我想我在那里对人们理解/知道的东西做了一些假设。人们坚持使用存储库模式有两个主要原因。1) 单元测试,2)查询重用。单元测试现在很容易在EF和IDbContext中进行。查询重用也可以处理,尽管我相信通过组件驱动的开发,组件之间的实际查询使用几乎没有重叠,所以您只需要在组件级别进行管理,这很容易做到……但我还是更喜欢利用EF/IQueryable的灵活性。实体框架是可模拟的。。。。现在。你是
var repository = new ....Repository();
var operation = new DinnerOperation( repository );

operation.GetDinner(5);
public interface IDinnerContext : IDisposable
{
    IDbSet<Dinner> Dinners;

    int SaveChanges();
}