JonPSmith / EfCore.TestSupport

Tools for helping in unit testing applications that use Entity Framework Core
https://www.thereformedprogrammer.net/new-features-for-unit-testing-your-entity-framework-core-5-code/
Other
352 stars 53 forks source link

EfSchemaCompare Does not detect missing Alternate Key #34

Closed davisnw closed 3 years ago

davisnw commented 4 years ago

Testing with EfCore.TestSupport 3.1.1 nuget package.

I don't see this listed in https://github.com/JonPSmith/EfCore.TestSupport/wiki/EfSchemaCompare-limitations,

It seems like it should be able to be treated similarly to a unique index, which is detected when missing.

Duplication:

CREATE DATABASE [FooDb]
GO

USE [FooDb]
GO
CREATE TABLE [dbo].[Foos](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [FooName] [nvarchar](450) NOT NULL,
    CONSTRAINT [PK_Foos] PRIMARY KEY CLUSTERED ([Id])
) ON [PRIMARY]
GO
public class Foo
{
    [Key]
    public int Id { get; set; }

    public string FooName { get; set; }
}

public class FooContext : DbContext
{
    public FooContext(DbContextOptions<FooContext> options) : base(options) { }

    public DbSet<Foo> Foos { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //Test passes, but shouldn't if HasAlternateKey is used.  EF generates in this case:
        //CONSTRAINT [AK_Foos_FooName] UNIQUE NONCLUSTERED ([FooName] ASC)
        modelBuilder.Entity<Foo>()
            .HasAlternateKey(x => x.FooName);

        //Test fails as expected if unique index configuration is used
        //modelBuilder.Entity<Foo>()
        //    .HasIndex(x => x.FooName)
        //    .IsUnique();
    }
}

public class FooTest
{
    [Fact]
    public void Blah()
    {
        //--------- Arrange ---------//
        string connectionString = "Server=(localdb)\\mssqllocaldb;Database=FooDb;Trusted_Connection=True;";
        var dbOptions = new DbContextOptionsBuilder<FooContext>().UseSqlServer(connectionString).Options;

        var config = new CompareEfSqlConfig();

        var comparer = new CompareEfSql(config);

        using (var fooContext = new FooContext(dbOptions))
        {
            //--------- Act ---------//
            var hasErrors = comparer.CompareEfWithDb(connectionString, fooContext);

            //--------- Assert ---------//
            Assert.False(hasErrors, comparer.GetAllErrors);
        }
    }
}
JonPSmith commented 4 years ago

Thank you for a very detailed issue. Yes that looks like a bug and I will try to look at it sometime, but it won't be soon. Making EfSchemaCompare work for all options is a challenge!

JonPSmith commented 3 years ago

I have split the EfSchemaCompare out into its own project and added a lots of features/fixes, especially around EF Core 5 new features.

I looked at checking alternative keys and its not easy, so I haven't implemented it. I do now list "alternative keys" as a limitation in the documentation.