EF Core SQLite в исключении памяти: ошибка SQLite 1: «около MAX: синтаксическая ошибка»

Я создаю базу данных SQLite In Memory для модульного тестирования:

        var connection = new SqliteConnection("DataSource=:memory:");
        connection.Open();

        try
        {
            var options = new DbContextOptionsBuilder<BloggingContext>()
                .UseSqlite(connection)
                .Options;

            // Create the schema in the database
            using (var context = new BloggingContext(options))
            {
                context.Database.EnsureCreated();
            }

            // Run the test against one instance of the context
            using (var context = new BloggingContext(options))
            {
                var service = new BlogService(context);
                service.Add("http://sample.com");
            }

            // Use a separate instance of the context to verify correct data was saved to database
            using (var context = new BloggingContext(options))
            {
                Assert.AreEqual(1, context.Blogs.Count());
                Assert.AreEqual("http://sample.com", context.Blogs.Single().Url);
            }
        }

context.Database.EnsureCreated (); завершается ошибкой с исключением: Сообщение: Microsoft.Data.Sqlite.SqliteException: SQLite Ошибка 1: 'рядом с "MAX": синтаксическая ошибка'.

Существует проблема с github, в которой говорится: Проблема здесь в том, что varchar (max) - это SqlServer конкретный тип. Каркас не должен добавлять его как реляционный тип, который передается в миграцию другими поставщиками, которые могут генерировать недопустимый sql при миграции.

Но как тогда я могу использовать SQLite в памяти для модульных тестов, если моя база данных содержит много столбцов varchar (max)?


person Deivydas Voroneckis    schedule 30.11.2018    source источник
comment
Если вы используете EF Core, почему бы не использовать поставщика In Memory вместо SQLite?   -  person DavidG    schedule 30.11.2018
comment
@DavidG Я использую в базе данных SQLite в памяти ссылку , потому что мне нужно тестировать транзакции.   -  person Deivydas Voroneckis    schedule 30.11.2018
comment
Если вы используете «Migrate» вместо «EnsureCreated»?   -  person Silvermind    schedule 30.11.2018
comment
@Silvermind Я пробовал это, но потом получаю другое исключение. Когда я вызываю _offerContext.Set<Aggregate>().FindAsync(id);, я получаю исключение: typeof (Microsoft.Data.Sqlite.SqliteException): SQLite Error 1: «нет такой таблицы: предложения». ---- Microsoft.Data.Sqlite.SqliteException: ошибка SQLite 1: «нет такой таблицы: предложения». вместо null. Если я передаю идентификатор существующей сущности, он возвращает правильный объект. Но я хочу проверить поведение, когда не нахожу сущность.   -  person Deivydas Voroneckis    schedule 30.11.2018


Ответы (1)


Я не нашел прямого решения, но начал использовать обходной путь с файлами конфигурации. Вы не указали, используете ли вы конфигурации EF, поэтому извините за основы, если они не нужны.

В вашем DbContext поместите следующее:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.ApplyConfigurationsFromAssembly(typeof(ChildrensSsiContext).Assembly);
}

Теперь создайте статический класс, как показано ниже. Он заберет вашу собственность и займется настройкой.

internal static class ConfigurationHelper
{
    internal static void ConfigureVarcharMax(PropertyBuilder<string> propertyBuilder, bool isRequired = true)
    {
        propertyBuilder
            .IsRequired(isRequired)
            //.HasColumnType("varchar(max)");
            .HasColumnType("text");
    }
}

Создайте класс конфигурации для каждой сущности, которую вы хотите настроить.

public class MyEntityWithVarcharMaxConfiguration
    : IEntityTypeConfiguration<MyEntityWithVarcharMax>
{
    public void Configure(EntityTypeBuilder<MyEntityWithVarcharMax> builder)
    {
        ConfigurationHelper.ConfigureVarcharMax(builder.Property(e => e.MyVarcharMaxProperty));
    }
}

Оставьте HasColumnType ("текст") без комментариев для тестирования. Затем прокомментируйте эту строку и раскомментируйте HasColumnType ("varchar (max)") при добавлении миграции.

Это больно, и вам нужно помнить об этом, но это довольно простой обходной путь.

person PretzelSteelersFan    schedule 30.12.2018