Подтвердить что ты не робот

Почему DbContext не реализует интерфейс IDbContext?

Почему в Entity Framework нет интерфейса IDbContext? Не было бы легче проверить вещи, если бы существовал интерфейс с такими методами, как SaveChanges() и т.д., Из которого вы могли бы получить свой пользовательский контекстный интерфейс базы данных?

public interface ICustomDbContext : IDbContext
{
    // add entity set properties to existing set of methods in IDbContext
    IDbSet<SomeEntity> SomeEntities { get; }
}
4b9b3361

Ответ 1

Я вижу это IDbContext:

См. эту ссылку И затем вы создадите новый частичный класс для интерфейса Entities Context With That.

public partial class YourModelEntities : DbContext, IDbContext 

Редакция: Я отредактировал этот пост, This Works for me. Мой контекст

namespace dao
{
    public interface ContextI : IDisposable
    {
        DbSet<TEntity> Set<TEntity>() where TEntity : class;
        DbSet Set(Type entityType);
        int SaveChanges();
        IEnumerable<DbEntityValidationResult> GetValidationErrors();
        DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity:class;
        DbEntityEntry Entry(object entity);
        string ConnectionString { get; set; }
        bool AutoDetectChangedEnabled { get; set; }
        void ExecuteSqlCommand(string p, params object[] o);
        void ExecuteSqlCommand(string p);
    }
}

YourModelEntities - это ваш автоматически генерируемый частичный класс, и вам нужно создать новый частичный класс с тем же именем, а затем добавить новый контекстный интерфейс, для этого примера ContextI

ПРИМЕЧАНИЕ. Интерфейс не реализовал все методы, поскольку методы реализованы в вашем автоматическом генерации кода.

namespace dao
{
    public partial class YourModelEntities :DbContext, ContextI
    {
        public string ConnectionString
        {
            get
            {
                return this.Database.Connection.ConnectionString;
            }
            set
            {
                this.Database.Connection.ConnectionString = value;
            }
        }

        bool AutoDetectChangedEnabled
        {
            get
            {
                return true;
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public void ExecuteSqlCommand(string p,params object[] os)
        {
            this.Database.ExecuteSqlCommand(p, os);
        }

        public void ExecuteSqlCommand(string p)
        {
            this.Database.ExecuteSqlCommand(p);
        }

        bool ContextI.AutoDetectChangedEnabled
        {
            get
            {
                return this.Configuration.AutoDetectChangesEnabled;
            }
            set
            {
                this.Configuration.AutoDetectChangesEnabled = value;
            }
        }

    }
}

Ответ 2

Я тоже думал об этом, я предполагаю, что вы собираетесь использовать его для насмешки DbContext. Я не нахожу причин для этого, за исключением того, что вам нужно будет вручную реализовать свой собственный DbSet вручную для вашего издевающегося класса (так что в любом случае вам придется переписать свой собственный интерфейс).

Ответ 3

Просто создайте макет DbContext, расширяющий вашу продукцию DbContext, переопределяя методы, которые усложняют тестирование. Таким образом, любые изменения в производственном DbContext автоматически отражаются в тестах, за исключением переопределенных методов. Для любых других классов, которые занимаются персистентностью и берут DbContext, просто расширяйте их, а также передавая расширенный макет DbContext.

namespace Test.Mocks
{  
    public sealed class MockDatabaseContext : MainProject.Persistence.Database.DatabaseContext
    {
        public MockDatabaseContext(ConfigurationWrapper config) : base(config)
        {

        }      
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {

            var dbPath = "test.db";
            optionsBuilder.UseSqlite($"Filename={dbPath}");


        }
    }
}

namespace Test.Mocks
{

    public class MockInventoryFacade : InventoryFacade
    {        
        public MockInventoryFacade(MockDatabaseContext databaseContext) : base(databaseContext)
        {

        }    
    }
}

Ответ 4

Нет IDbContext, потому что это было бы бесполезно, единственной его реализацией был бы DbContext.

Команда EF также идет по этому пути с IDbSet, если вы посмотрите на это заметку о дизайне проекта

Для меня реальная проблема с EF, когда речь идет о модульном тестировании, - это DbConnection в DbContext, к счастью, есть Effort a хороший проект на codeplex, который начинает заполнять это.

Effort - это мощный инструмент, который позволяет создать автоматизированные тесты для приложений на основе Entity Framework.  Это, в основном, поставщик ADO.NET, который выполняет все операции с данными в облегченной базе данных основной памяти в процессе работы вместо традиционной внешней базы данных. Он также предоставляет некоторые интуитивные вспомогательные методы, которые действительно упрощают использование этого провайдера с существующими классами ObjectContext или DbContext. Простое дополнение к существующему коду может быть достаточно для создания тестов, управляемых данными, которые могут выполняться без наличия внешней базы данных.

С этим вы можете оставить свой DbContext и DbSet как есть, и легко выполнять ваши модульные тесты. Единственным недостатком этого является различие между провайдерами Linq, где некоторые модульные тесты могут проходить с усилием, а не с реальным бэкэндом.

ОБНОВЛЕНИЕ с EF7

Я все еще утверждаю, что IDbContext бесполезен, и проблема возникает из DbConnection.

EF7 также не будет иметь IDbContext, чтобы выполнить модульное тестирование, которое теперь предоставляет провайдер в памяти.

Вы видите, как Роуэн Миллер делает демо: Современные приложения данных с платформой Entity Framework 7