5 votes

EF Core SQLite dans une exception de mémoire : Erreur SQLite 1 : 'near "MAX" : syntax error'

Je crée une base de données SQLite In Memory pour des tests unitaires :

        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() ; échoue avec une exception : Message : Microsoft.Data.Sqlite.SqliteException : Erreur SQLite 1 : 'near "MAX" : syntax error'.

Il y a problème github dire : Le problème est que varchar(max) est un type spécifique à SqlServer. L'échafaudage ne devrait pas l'ajouter en tant que type relationnel qui est transmis à la migration dans d'autres fournisseurs, ce qui est susceptible de générer un SQL invalide lors de la migration.

Mais comment puis-je utiliser SQLite in Memory pour les tests unitaires si ma base de données contient de nombreuses colonnes varchar(max) ?

0voto

Je n'ai pas trouvé de solution directe, mais j'ai commencé à utiliser une solution de contournement pour les fichiers de configuration. Vous n'avez pas indiqué si vous utilisiez des configurations EF, alors excusez les bases si elles ne sont pas nécessaires.

Dans votre DbContext, placez ce qui suit :

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

Créez maintenant une classe statique comme ci-dessous. Elle va prendre votre propriété et gérer la configuration.

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

Créez une classe de configuration pour chaque entité que vous souhaitez configurer.

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

Laissez la ligne HasColumnType("text") sans commentaire pour les tests. Commentez ensuite cette ligne et décommentez HasColumnType("varchar(max)") lorsque vous ajoutez la migration.

Il est pénible de devoir s'en souvenir, mais c'est une solution assez simple.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X