msmolcic
msmolcic

Reputation: 6577

EF Core DB first mapping PostgreSQL bit(1) column as BitArray instead of bool

I'm connecting with EF Core to the existing PostgreSQL database. There is a non-nullable flag column IsAvailable defined as bit(1). Scaffolded entity ends up with BitArray IsAvailable property where I expected it to be a bool. I tried changing the type manually but I end up with an exception when I query the data.

The property 'Loan.IsAvailable' is of type 'bool' which is not supported by the current database provider. Either change the property CLR type or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

I also tried playing around with the private field, [NotMapped] property, and [Column("is_available")] attribute on the field, but that was not working either. Has anyone encountered this issue before? What can I do about it?

Column definition in entity configuration

entity.Property(e => e.IsAvailable)
    .IsRequired()
    .HasColumnType("bit(1)")
    .HasColumnName("is_available");

Upvotes: 1

Views: 3910

Answers (3)

DavidC
DavidC

Reputation: 704

Although it is implicit on djbobo's answer, the first change to consider in this case (if possible) is to turn the column on the PostgreSQL database into a boolean, which should be used to store boolean data.

Here is a good explanation:

https://dba.stackexchange.com/a/156851/123694

Upvotes: 0

msmolcic
msmolcic

Reputation: 6577

ValueConverters were what I needed, I stumbled upon them in the official docs.

Ended up creating one of my own for this type of conversion.

Converter definition

public static class ConverterProvider
{
    public static ValueConverter<bool, BitArray> GetBoolToBitArrayConverter()
    {
        return new ValueConverter<bool, BitArray>(
            value => new BitArray(new[] { value }),
            value => value.Get(0));
    }
}

Column mapping

entity.Property(e => e.IsCurrent)
    .IsRequired()
    .HasColumnType("bit(1)")
    .HasColumnName("is_current")
    .HasConversion(ConverterProvider.GetBoolToBitArrayConverter());

And I swapped the property to bool IsAvailable within my entity manually.

Upvotes: 1

djbobo
djbobo

Reputation: 547

You can add a bool non mapped property in c# as a proxy to bitarray if you cannot change dB type to boolean.

[Column("is_available")]
public BitArray IsAvailableField {get;set;}

[NotMapped]
public boolean IsAvailable {
  get {
    return IsAvailableField[0];
  }
  set {
    IsAvailableField[0] = value;
  }
}

Upvotes: 0

Related Questions