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

Exception occurs when checking tables without PK #17

Closed dvoreckyaa closed 5 years ago

dvoreckyaa commented 5 years ago

Hi Jon, I very like your tool, but I faced with some issue during using it. Firstly, exception occurs when checking tables without PK (null reference exception). Unfortunatelly, I have not saved a log. But I've made a quick fix by using null propagation, for example:

public bool CompareModelToDatabase(DatabaseModel databaseModel)
{
//.....
logger.CheckDifferent(entityType.FindPrimaryKey().Relational().Name, databaseTable.PrimaryKey**?**.Name,
                        CompareAttributes.ConstraintName);
//.....
}

And

private void CompareColumns(CompareLog log, IEntityType entityType, DatabaseTable table)
 {
      var columnDict = table.Columns.ToDictionary(x => x.Name);
      var primaryKeyDict = table.PrimaryKey == null ? new Dictionary<string, DatabaseColumn>() : table.PrimaryKey.Columns.ToDictionary(x => x.Name);
//....
  pKeyLogger.CheckDifferent(efPKeyConstraintName, table.PrimaryKey?.Name, CompareAttributes.ConstraintName);

This is just a quick fix, because the absence of PK is identified as “DIFFERENCE”. Thanks.

JonPSmith commented 5 years ago

Hi @dvoreckyaa,

Thanks for the heads up on this issue. I assume you have a DbQuery in your DbContext - is that correct? I can see that would cause a problem. If you have any more information on this then please add it to this issue.

I am very busy at the moment so it will be some weeks before I can look at this. I also have issue #15 to look at.

dvoreckyaa commented 5 years ago

@JonPSmith , I have a DbContext with, for example, tables A, B, C. The database has tables A, B, C and D. D has no PK. Then I run a comparison for this context and the corresponding database, and an error occurs when I try to compare Table D, because it does not have a PK.

JonPSmith commented 5 years ago

Hi @dvoreckyaa,

Sorry, misunderstood. Proper answer below.

I had a quick look at my code and with EF Core a table/view without a primary key must be mapped to DbQuery<T>, not a DbSet<T> (see the Microsoft docs on Query Types about the differences between normal entity types and query types).

My code can't check DbQuery, because views are not handled by the EF Core scaffolder, so it excludes them from the check. This means if you map your table with no primary key to a DbQuery<T> then this error won't happen.

NOTE: This all changes in EF Core 3, but that is some way off.

dvoreckyaa commented 5 years ago

Hi @JonPSmith , the issue happened with a table that was not mapped to any table in DbContext. And this table should not be in DbContext. It may not be intended to compare such context and database, but perhaps, in this case, it is possible to prevent an error? I am talking only about EfSchemeCompare. Thanks.

JonPSmith commented 5 years ago

Hi @dvoreckyaa,

OK, I misunderstood - that makes more sense. I should have focused on your other issue, but that looked like a request for a new feature.

I think you know what I'm going to say - you exclude tables by creating a CompareEfSqlConfig and setting TablesToIgnoreCommaDelimited property with the tables you want to exclude, e.g. "MyTableToExclude,AnotherTableToExclude". If you include all the tables that don't map to EF Core entities/queries then that will stop that problem.