kostas.kapasakis
kostas.kapasakis

Reputation: 1152

Can I use an existing nullable column as a Discriminator in Entity Framework?

I have been searching for a clear answer in the Docs for this but could not find one.

My use case is that I have an existing table using an "unofficial" table-per-hierarchy (TPH) . It is using a column with different values that is later mapped based with the null and not null value in the model.

As part of a refactoring we want to map it correctly in EF but unfortunately we dont have a great amount of freedom as this column is used in the legacy system mapping as well.

My main question is by having a configuration as below I am getting a runtime "Data is null error".

       tableBase
            .HasDiscriminator<string>(nameof(tableBase.ExistinColumn))
            .HasValue<Child1>(null)
            .HasValue<Child2>("string1")
            .HasValue<Child2>("string2")
            .HasValue<Child2>("string3");

As you can see this column takes 4 values , null should be mapped with the Child1 class and all the rest of them with the Child2 class.

Not sure if thats the way and I have misconfigured this.

Is creating a new column and with a migration script populate it based on the existing column value and finally use it as a discriminator the only way to achieve this ?

This would be of course the best way to do it but I am not sure what kind of issues it will lead in the legacy system.

Thanks in advance,

Upvotes: 1

Views: 124

Answers (1)

kostas.kapasakis
kostas.kapasakis

Reputation: 1152

As mentioned also in the comments , I tried the solution with a new column. In a POC state of course but it seems to be working fine.

Steps.

  1. Created a Discriminator int computed column which takes the values from a scalar function that returns the discriminator value by wrapping the cases.
  • 0 when Column Value is null
  • 1 when string1
  • 2 when string2
  • 3 when string3
  • -1 when none of them.
  1. Created a NotMapped int Discriminator property in TableBase class.
  1. EF Mapping modified to below

        tableBase
             .HasDiscriminator<int>(nameof(tableBase.Discriminator))
             .HasValue<Child1>((int)DeriveTypesEnum.Child1)
             .HasValue<Child2>((int)DeriveTypesEnum.Child2)
             .HasValue<Child3>((intDeriveTypesEnum.Child3)
             .HasValue<Child4> ((int)DeriveTypesEnum.Child4);
    

Upvotes: 1

Related Questions