Заполнение базы данных вручную с помощью Entity Framework 6 в модульном тесте - PullRequest
0 голосов
/ 01 июля 2019

Я пишу модульный тест, который включает тестирование пробелов в столбцах идентификаторов. Я использую базу данных EFFORT в памяти для тестирования в Entity Framework 6 и пытаюсь заполнить базу данных в начале модульного теста.

Вот пример макета базы данных:

public class ProdDbContext : DbContext
{
    public ProdDbContext(DbConnection existingConnection, bool contextOwnsConnection);
    public DbSet<One> One { get; set; }
    public DbSet<Two> Two { get; set; }
}

public class One
{
    public One();
    [Key] public int Id { get; set; }
    [ForeignKey("Two")] public int? TwoId { get; set; }
    public virtual Two Two { get; set; }
}

public class Two
{
    public Two();
    [Key] public int Id { get; set; }
    [Required] public string Name { get; set; }
}

Конечно, при попытке сделать Two.Add () он игнорирует Id, который я специально установил. Поэтому после прочтения этого я обнаружил OnModelCreating, который позволяет отдельному DbContext использовать другой построитель моделей:

public class SeedingDbContext : ProdDbContext
{
    protected override void OnModelCreating(DbModelBuilder dbModelBuilder)
    {
        dbModelBuilder.Entity<One>().Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        dbModelBuilder.Entity<Two>().Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        base.OnModelCreating(dbModelBuilder);
    }
}

public class NonSeedingDbContext : ProdDbContext
{
    protected override void OnModelCreating(DbModelBuilder dbModelBuilder)
    {
        // Method is for test only (i.e. setting a breakpoint)
        base.OnModelCreating(dbModelBuilder);
    }
}

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

Так что при поиске ответа я столкнулся с IDbModelCacheKeyProvider и CacheKey. Подумав, может быть, это поможет запустить Entity Framework для использования правильной модели, я реализовал это:

public class SeedingDbContext : ProdDbContext, IDbModelCacheKeyProvider
{
    public string CacheKey => nameof(SeedingDbContext);
    protected override void OnModelCreating(DbModelBuilder dbModelBuilder)
    {
        dbModelBuilder.Entity<One>().Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        dbModelBuilder.Entity<Two>().Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        base.OnModelCreating(dbModelBuilder);
    }
}

public class NonSeedingDbContext : ProdDbContext, IDbModelCacheKeyProvider
{
    public string CacheKey => nameof(NonSeedingDbContext);
    protected override void OnModelCreating(DbModelBuilder dbModelBuilder)
    {
        // Method is for test only (i.e. setting a breakpoint)
        base.OnModelCreating(dbModelBuilder);
    }
}

К сожалению, это, похоже, не имеет никакого эффекта.

Это поведение работает и в обратном направлении. Если я сначала попытаюсь использовать NonSeedingDbContext, в результате чего сначала будет создана его модель, то, следовательно, заполнение никогда не будет использоваться в Entity Framework, даже если я использую SeedingDbContext.

Может кто-нибудь сказать мне, как заставить Entity Framework принудительно использовать построитель моделей, о котором я говорю?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...