Book Image

Entity Framework Core Cookbook - Second Edition

By : Ricardo Peres
Book Image

Entity Framework Core Cookbook - Second Edition

By: Ricardo Peres

Overview of this book

Entity Framework is a highly recommended Object Relation Mapping tool used to build complex systems. In order to survive in this growing market, the knowledge of a framework that helps provide easy access to databases, that is, Entity Framework has become a necessity. This book will provide .NET developers with this knowledge and guide them through working efficiently with data using Entity Framework Core. You will start off by learning how to efficiently use Entity Framework in practical situations. You will gain a deep understanding of mapping properties and find out how to handle validation in Entity Framework. The book will then explain how to work with transactions and stored procedures along with improving Entity Framework using query libraries. Moving on, you will learn to improve complex query scenarios and implement transaction and concurrency control. You will then be taught to improve and develop Entity Framework in complex business scenarios. With the concluding chapter on performance and scalability, this book will get you ready to use Entity Framework proficiently.
Table of Contents (15 chapters)
Entity Framework Core Cookbook - Second Edition
Credits
About the Author
About the Reviewer
www.PacktPub.com
Preface
Index

Creating mock database connections


When working with Entity Framework in a test-driven manner, we need to be able to slip a layer between our last line of code and the framework. This allows us to simulate the database connection without actually hitting the database.

We will be using the NuGet Package Manager to install the Entity Framework Core 1 package, Microsoft.EntityFrameworkCore. We will also be using a SQL Server database for storing the data, so we will also need Microsoft.EntityFrameworkCore.SqlServer.

To mock interfaces and base classes, we will use Moq.

Finally, xunit is the package we will be using for the unit tests and dotnet-text-xunit adds tooling support for Visual Studio. Note that the UnitTests project is a .NET Core App 1.0 (netcoreapp1.0), that Microsoft.EntityFrameworkCore.Design is configured as a build dependency, and Microsoft.EntityFrameworkCore.Tools is set as a tool.

Open Using EF Core Solution from the included source code examples.

Execute the database setup script from the code samples included for this recipe. This can be found in the DataAccess project within the Database folder.

How to do it…

  1. In the DataAccess project, add a new C# interface named IDbContext using the following code:

    using System.Linq;
    namespace DataAccess
    {
        public interface IDbContext
        {
            IQueryable<T> Set<T>() where T : class;
        }
    }
  2. Add a new unit test in the UnitTests project to test so we can supply dummy results for fake database calls with the following code:

    using System.Linq;
    using DataAccess;
    using BusinessLogic;
    using Moq;
    using Xunit;
    namespace UnitTests
    {
        public class MockTest : BaseTest
        {      
            [Fact]
            public void CanMock()
            {
               //Arrange
                var data = new[] { new Blog { Id = 1, Title = "Title" }, newBlog { Id = 2, Title = "No Title" } }.AsQueryable();
                var mock = new Mock<IDbContext>();
                mock.Setup(x => x.Set<Blog>()).Returns(data);
                //Act
                var context = mock.Object;
                var blogs = context.Set<Blog>();
                //Assert
                Assert.Equal(data, blogs);
            }
        }
    }
  3. In the DataAccess project, update the C# class named BlogContext with the following code:

    using BusinessLogic;
    using System.Linq;
    using Microsoft.EntityFrameworkCore;
    namespace DataAccess
    {
        public class BlogContext : DbContext, IDbContext
        {
            private readonly string _connectionString;
            public BlogContext(string connectionString)
            {
                _connectionString = connectionString;
            }
            public DbSet<Blog> Blogs { get; set; }
            IQueryable<T> IDbContext.Set<T>()
            {
                return base.Set<T>();  
            }
            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            {
                optionsBuilder.UseSqlServer(_connectionString);
                base.OnConfiguring(optionsBuilder);
            }
            public void Rollback()
            {
                ChangeTracker.Entries().ToList().ForEach(x =>
                {
                    x.State = EntityState.Detached;
                    var keys = GetEntityKey(x.Entity);
                    Set(x.Entity.GetType(), keys);
                });
            }
        }
    }

How it works…

We implemented a fake class —a mock—that mimics some of the functionality of our IDbContext interface that we wish to expose and make testable; in this case, it is just the retrieval of data. This allows us to keep our tests independent of the actual data in the database. Now that we have data available from our mock, we can test whether it acts exactly like we coded it to. Knowing the inputs of the data access code, we can test the outputs for validity. We made our existing BlogContext class implement the interface where we define the contract that we wish to mock, IDbContext, and we configured a mock class to return dummy data whenever its Set method was called.

This layering is accomplished by having a Set method as an abstraction between the public framework method of Set<T> and our code, so we can change the type to something constructible. By layering this method, we can now control every return from the database in the test scenarios.

This layering also provides a better separation of concerns, as the DbSet<T> in Entity Framework mingles multiple independent concerns, such as connection management and querying, into a single object, whereas IQueryable<T> is the standard .NET interface for performing queries against a data source (DbSet<T> implements IQueryable<T>). We will continue to separate these concerns in future recipes.

See also

In this chapter:

  • Unit testing and mocking