NET 9 Object reference not set to an instance of an object.
After migrate from net8 to net9 I get the following error
Have the same issue when DbContext.Database.Migrate or MigrateAsync is called.
Provide minimal steps to reproduce the issue.
Provide minimal step to reproduce the issue.
First migration create 3 Tables with different column types like what: String Int32 Bool DateTime64(7) Decimal128(4)
Some columns nullable TableEngine: MergeTree OrderBy: "xxHash32(SchoolId)", "intHash32(Type)" PartitionBy: "toYYYYMM(CreatedDate)", "Type"
SchoolId - String, Type - Int32, CreatedDate - DateTime64(7)
Second migration create indexes like what:
migrationBuilder.Sql("ALTER TABLE \"SiteGuestSessions\" ADD INDEX SchoolId_idx (SchoolId) TYPE minmax GRANULARITY 1;");
migrationBuilder.Sql("ALTER TABLE \"SiteGuestSessionViews\" ADD INDEX SchoolId_idx (SchoolId) TYPE minmax GRANULARITY 1;");
migrationBuilder.Sql("ALTER TABLE \"Conversions\" ADD INDEX SchoolId_idx (SchoolId) TYPE minmax GRANULARITY 1;");
migrationBuilder.Sql("ALTER TABLE \"SiteGuestSessionViews\" ADD INDEX SessionId_idx (SessionId) TYPE minmax GRANULARITY 1;");
migrationBuilder.Sql("ALTER TABLE \"Conversions\" ADD INDEX SiteViewId_idx (SiteViewId) TYPE minmax GRANULARITY 1;");
migrationBuilder.Sql("ALTER TABLE \"SiteGuestSessions\" ADD INDEX SchoolId_StartDate_idx (SchoolId, StartDate) TYPE minmax GRANULARITY 1;");
Third migration added columns
migrationBuilder.AddColumn<DateTime>(
name: "UpdatedDate",
table: "Conversions",
type: "DateTime64(7)",
nullable: true);
@denis-ivanov The issue is marked as resolved, but there are no commits yet, when can we expect a version with a fix to be released?
Yes - in case when you provide good steps to reproduce.
Yes - in case when you provide good steps to reproduce.
https://drive.google.com/file/d/1wU9hhmjsMlosVa31x5IB_oOKByCguPXP/view?usp=sharing
cd ClickHouseTest dotnet ef database update --context ClickHouseContext
@denis-ivanov is the project above enough to open an issue or not?
@denis-ivanov The problem is using the Decimal128(4) type, which is actually cast to Decimal(38, 4), when I switched to using Decimal(38, 4), the error disappeared, but a new one appeared
The new error was related to AcquireDatabaseLock and AcquireDatabaseLockAsync because they are not implemented, to bypass this problem the code of NpgsqlHistoryRepository was taken as an example, namely the implementation of NpgsqlMigrationDatabaseLock
After override
After these manipulations, migrations are successfully created.
But the GetCreateIfNotExistsScript method worked incorrectly, so I had to fix it too.
@denis-ivanov I can confirm that this issue can be reproduced with the sample code that is available in readme. Does anybody know which version is working? Seems that downgrading version to 0.0.22 with dotnet 8 also has some issues
Older versions have issue:
Unhandled exception. System.TypeLoadException: Method 'get_LockReleaseBehavior' in type 'ClickHouse.EntityFrameworkCore.Migrations.Internal.ClickHouseHistoryRepository' from assembly 'EntityFrameworkCore.ClickHouse, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
Sorry, the file you have requested does not exist.
Make sure that you have the correct URL and the file exists.
It is very easily reproducible problem.
It seems that if the column definition is done through [Column(TypeName ="decimal(x, y")] or .HasColumnType("decimal(x, y)") the update and any other follow up entity framework operation fails.
My best guess is that the type converter lookup fails somewhere for some reason when the column type is defined through this approach. It works when HasPrecision is used.
Also the identified code works correctly with MSSQL/NPSQL/SQLITE.
I managed to trigger this with these two simple classes:
public class Test {
// Either annotate column with this
// [Column(TypeName = "decimal(20, 8)")]
public decimal? Foo {get; set;}
}
public class TestDbContext : DbContext {
public TestDbContext(DbContextOptions<TestDbContext> options) : base(options) {}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Or use fluent builder like this
modelBuilder.Entity<Test>().Property(p => p.Foo).HasColumnType("decimal(20,8)");
// This way of indicating precision does not trigger the null pointer
// modelBuilder.Entity<Test>().Property(p => p.Foo).HasPrecision(20,8);
}
}
And for the sake of complete project here is also the design time factory:
public class TastDbContextFactory : IDesignTimeDbContextFactory<TestDbContext> {
public TestDbContext CreateDbContext(string[] args) {
var cs = "Host=localhost;Protocol=http;Port=8123;Database=default;User Id=default;Password=default";
var optionsBuilder = new DbContextOptionsBuilder<TestDbContext>();
optionsBuilder.UseClickhouse(cs, opts => {});
return new TestDbContext(optionsBuillder.Options);
}
}
I spent roughly 2 days to get the EF Core build, ef executable etc working, and as EF framwork code is all very fancy code with lambdas generics et al I gave up on the challenge of become the EF Core expert after I found that there is a workaround :( ).