简体   繁体   English

您是否将存储库模式与Entity Framework一起使用?

[英]Do you use repository pattern with Entity Framework?

Some people say we shouldn't use repository and unit of work patter because repository & UnitOfWork just duplicates what Entity Framework (EF) DbContext give you anyway. 有些人说我们不应该使用存储库和工作单元模式,因为存储库和UnitOfWork只是复制实体框架(EF)DbContext给你的东西。 But if I use repositories I can write easy unit test for services because I can mock methods from repositories (which return data from database using linq queries), for example: 但是如果我使用存储库,我可以为服务编写简单的单元测试,因为我可以从存储库模拟方法(使用linq查询从数据库返回数据),例如:

Repository: 库:

public class CommentsRepository : ICommentsRepository
{
    public CommentsRepository(DatabaseContext context)
        : base(context)
    {
    }

    public IEnumerable<Comment> GetComments()
    {
        return context.Comments.Include(x => x.Note).OrderByDescending(x => x.CreatedDate).ToList();
    }
}

Service: 服务:

public class CommentsService : ICommentsService
{
    private ICommentsRepository _commentsRepository;

    public CommentsService(ICommentsRepository commentsRepository)
    {
        _commentsRepository = commentsRepository;
    }

    public IEnumerable<Comment> GetComments()
    {
        List<Comment> comments = _commentsRepository.GetComments().ToList();

        comments.ForEach(x => x.Author = "Secret");

        return comments;
    }
}

Unit test for service: 服务单元测试:

[TestClass]
public class CommentsServiceTest
{
    [TestMethod]
    public void GetCommentsTest()
    {
        // Arrange
        IList<Comment> comments = Builder<Comment>.CreateListOfSize(2)
            .Build();

        AutoMoqer mocker = new AutoMoqer();
        mocker.GetMock<ICommentsRepository>()
                .Setup(x => x.GetComments())
                .Returns(comments);

        // Act
        ICommentsService commentsService = mocker.Resolve<CommentsService>();
        IList<Comment> result = commentsService.GetComments().ToList();

        // Assert
        Assert.AreEqual("Secret", result[0].Author);
        Assert.AreEqual("Secret", result[1].Author);
    }
}

Now when I eliminate repository I must write linq queries inside services: 现在当我消除存储库时,我必须在服务中编写linq查询:

public class CommentsService : ICommentsService
{
    private DatabaseContext _context;

    public CommentsService(DatabaseContext context)
    {
        _context = context;
    }

    public IEnumerable<Comment> GetComments()
    {
        List<Comment> comments = _context.Comments.Include(x => x.Note).OrderByDescending(x => x.CreatedDate).ToList();

        comments.ForEach(x => x.Author = "Secret");

        return comments;
    }
}

Writing unit test for that service is problematic because I must mock: 为该服务编写单元测试是有问题的,因为我必须模拟:

context.Comments.Include(x => x.Note).OrderByDescending(x => x.CreatedDate)

So what do you do? 所以你会怎么做? Do you write repository classes or not? 你是否编写了存储库类? If not, how do you mock linq queries? 如果没有,你如何模拟linq查询?

As with all patterns, if it suits your purposes then you should use it. 与所有模式一样,如果它适合您的目的,那么您应该使用它。

I wrote a unit of work and repository pattern implementation that wrapped Entity Framework. 我编写了一个包含Entity Framework的工作单元和存储库模式实现。 Not only so I could do tests, but to abstract EF away from the rest of my application. 不仅如此,我还可以进行测试,而是将EF从我的应用程序的其余部分中抽象出来。

It made later switching to an in memory database for 'live' testing an absolute breeze. 它后来切换到内存数据库进行“实时”测试,这是一个绝对的微风。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM