Search code examples
c#sql-serversqliteunit-testingentity-framework-core

How to determine if provider is for SQL Server or SQLite?


I am configuring my entities by having an EntityConfiguration class that implements IEntityTypeConfiguration<MyEntity>.

For normal application execution I am using SQL Server and for unit testing I am using SQLite.

The issue is that the SQLite provider has limited features, so I would like to conditionally configure my entities so that if it is using SQL Server, it has additional features, such as RowVersion:

entity.Property(e => e.RowVersion)
      .IsRequired(true)
      .IsRowVersion()
      .IsConcurrencyToken();

How can I tell which db provider is being used?


Solution

  • Comments to the question give good reasoning why NOT to do it in the code - use the same type of the database in your tests.

    But if you still want to do it - I could only think of putting this logic both in the db context and entity type configuration. Please see demo below

    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Metadata.Builders;
    using Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal;
    using Microsoft.Extensions.DependencyInjection;
    
    var serviceCollection = new ServiceCollection();
    serviceCollection.AddDbContext<AppDbContext>(builder => builder.UseSqlServer("xxx"));
    var serviceProvider = serviceCollection.BuildServiceProvider();
    var dbContext = serviceProvider.GetRequiredService<AppDbContext>();
    // trigger entity configuration
    dbContext.Orders.ToList();
    
    
    public class Orders
    {
        public int Id { get; set; }
        public byte[] RowVersion { get; set; }
    }
    
    public class OrderConfiguration : IEntityTypeConfiguration<Orders>
    {
        private readonly string provider;
    
        public OrderConfiguration(string provider)
        {
            this.provider = provider;
        }
        
        public void Configure(EntityTypeBuilder<Orders> builder)
        {
            builder.HasKey(x => x.Id);
            
            if (provider == "SqlServer")
            {
                builder.Property(x => x.RowVersion)
                    .IsRequired(true)
                    .IsRowVersion()
                    .IsConcurrencyToken()
                    ;
            }
        }
    }
    
    public class AppDbContext : DbContext
    {
        public DbSet<Orders> Orders { get; set; }
    
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
        {
        }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            string provider = null;
            if (Database.IsSqlServer())
            {
                provider = "SqlServer";
            }
    
            // do this or load different configuration type for each provider
            modelBuilder.ApplyConfiguration(new OrderConfiguration(provider)); 
            
            base.OnModelCreating(modelBuilder);
        }
    }