zs2020
zs2020

Reputation: 54522

What is easiest way to deal with converting 0/1 to False/True in EF 4.x?

The stored Proc returns a column with the value to be either 0 or 1 without converting to BIT. In my POCO, if I declare the field as

public bool MyColumn {get; set;}

I am getting this error:

The specified cast from a materialized 'System.Int32' type to the 'System.Boolean' type is not valid.

This actually makes sense since EF recognizes the returned value as an integer.

I am wondering that is there any easy way to (add annotation or use fluent api maybe) automatically convert 0/1 to False/True in the mapping behind the scene without touching the Proc?

Thanks in advance!

Upvotes: 14

Views: 12054

Answers (5)

Jimmy
Jimmy

Reputation: 1072

In your ApplicationDbContext (the class that inherits from DbContext) you can use Fluent Api to convert values for the database.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  base.OnModelCreating(modelBuilder);
  modelBuilder.Entity<TheNameOfYourModelClass>()
    .Property(p => p.MyColumn)
    .HasConversion(
       v => v ? 1 : 0,
       v => (v == 1));
}

Now, your database will contain 1 when inserting a true for MyColumn and vice-versa. When reading from your database 1 will be converted to true and vice-versa.

Upvotes: 7

Nicholas Franceschina
Nicholas Franceschina

Reputation: 6147

building on what @jimmy provided, could also define the ValueConverter separately and then apply across multiple entities/properties:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var boolConverter = new ValueConverter<bool, int>(
        v => v ? 1 : 0,
        v => (v == 1) ? true : false);

    foreach (var entityType in modelBuilder.Model.GetEntityTypes())
    {
        foreach (var property in entityType.GetProperties())
        {
            if (property.ClrType == typeof(bool))
                property.SetValueConverter(boolConverter);
        }
    }
}

Upvotes: 2

Francisco Goldenstein
Francisco Goldenstein

Reputation: 13767

Another option is to return a BIT from the stored procedure so you don't need to cast anything at C# side or use any weird decoration. This means, you can cast the integer value to BIT in T-SQL like I do below:

select col1, col2, CONVERT(BIT, CASE WHEN col3 IS NULL THEN 0 ELSE 1 END) as colWithBit
FROM table1

Upvotes: 29

aikixd
aikixd

Reputation: 514

Use System.Convert.ToBoolean(int)

Upvotes: -4

Shyju
Shyju

Reputation: 218792

What you can do is to have another Property to represent the Boolean representation . Decorate it with NotMapped attribute so that EF won't consider it for Mapping. Do and If condition and return true /false based on the value of Other property.

public Class Customer
{

  [NotMapped]
  public bool MyColumnBool 
  {
      get
      {
         return (MyColumn ==1);
      }
  }

  public int MyColumn {get; set;}
  // other properties

}

Upvotes: 13

Related Questions