EntityFrameworkCore.ClickHouse icon indicating copy to clipboard operation
EntityFrameworkCore.ClickHouse copied to clipboard

NET 9 Object reference not set to an instance of an object.

Open AniMeIIIkA opened this issue 1 year ago • 11 comments

After migrate from net8 to net9 I get the following error image image

AniMeIIIkA avatar Dec 05 '24 12:12 AniMeIIIkA

Have the same issue when DbContext.Database.Migrate or MigrateAsync is called.

xxxmel avatar Dec 09 '24 04:12 xxxmel

Provide minimal steps to reproduce the issue.

denis-ivanov avatar Dec 10 '24 11:12 denis-ivanov

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);

AniMeIIIkA avatar Dec 10 '24 21:12 AniMeIIIkA

@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?

AniMeIIIkA avatar Dec 11 '24 10:12 AniMeIIIkA

Yes - in case when you provide good steps to reproduce.

denis-ivanov avatar Dec 11 '24 10:12 denis-ivanov

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

AniMeIIIkA avatar Dec 11 '24 11:12 AniMeIIIkA

@denis-ivanov is the project above enough to open an issue or not?

AniMeIIIkA avatar Dec 12 '24 12:12 AniMeIIIkA

@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

image After override image

After these manipulations, migrations are successfully created.

But the GetCreateIfNotExistsScript method worked incorrectly, so I had to fix it too. image

AniMeIIIkA avatar Dec 20 '24 11:12 AniMeIIIkA

@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.

gunpuz avatar Jan 06 '25 13:01 gunpuz

Sorry, the file you have requested does not exist.

Make sure that you have the correct URL and the file exists.

denis-ivanov avatar Jan 19 '25 17:01 denis-ivanov

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 :( ).

laazik avatar Feb 16 '25 11:02 laazik