简体   繁体   中英

How do I map a C# int to a SqlServer tinyint using Entity Framework Code First?

I have a POCO model class and an existing DB table, neither of which I am able to change I am using Entity Framework 6 and the Fluent API.

The model class has a CountryId of 'int'. However, in the database table, the CtryId is a 'tinyint'.

I tried to set the type using

modelBuilder.Entity<Event>().Property(e => e.CountryId).HasColumnName("CtryId").HasColumnType("tinyint");

in the OnModelCreating method but get the following error:

error 2019: Member Mapping specified is not valid. The type 'Edm.Int32[Nullable=False,DefaultValue=]' of member 'CountryId' in type 'RA.Data.Event' is not compatible with 'SqlServer.tinyint[Nullable=False,DefaultValue=]' of member 'CtryId' in type 'CodeFirstDatabaseSchema.Event'.

How do I map a C# int to a SqlServer tinyint using Entity Framework Code First?

Short answer : You can't.

The mappings "line up" like below.

The property on the POCO should be "byte".

    public byte CountryId{ get; set; }

and the Mapping:

        this.Property(t => t.CountryId).HasColumnName("CtryId");

You gotta play by the rules of EF.

However, the good news is that you can make it work with a little magic.

Since you don't want to break the contract..... you can do a workaround.

public byte JustForMappingCtryId{ get; set; }

[NotMapped]
public int CountryId
{ 
    get
    { 
        return Convert.ToInt32(this.JustForMappingCtryId);
    } 
    set
    {
        if(value > 8 || value < 0 )
        {
              throw new ArgumentOutOfRangeException("Must be 8 or less, and greater or equal to zero.");
        }
        //this.JustForMappingCtryId = value;  /* Uncomment this code.. to put back the setter... you'll have to do the conversion here (from the input int to the byte) of course..but the edited out code shows the intention */      
    }
}

and the mapping:

   this.Property(t => t.JustForMappingCtryId).HasColumnName("CtryId");

And put an entity framework "ignore" attribute on CountryId. (above seen as [NotMapped]) .. OR use the Fluent way to specify the ignore (not shown in the code above) but below is a breadcrumb:

 modelBuilder.Entity<MyEntity>().Ignore(c => c.MyPocoProperty);

There ya go. It is a workaround, but should fit your need.

In EF, int32 maps to int in the db. In this case, tinyint maps to byte in the .NET framework. You should change your CountryId to the type of byte in the POCO model.

You could create a new POCO class with byte column and use it instead of the old POCO class.

You could use AutoMapper to copy the values between old POCO class used in higher layers and new POCO class used in your repository layer for storing purposes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM