Почему 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; }
}
Ответы
Ответ 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