Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 547
Anthony Avatar asked Mar 28 '14 13:03

Anthony


People also ask

What is map in C?

What is a map in C++? A C++ map is a way to store a key-value pair. A map can be declared as follows: #include <iostream> #include <map> map<int, int> sample_map; Each map entry consists of a pair: a key and a value.

Is there mapping in C?

Note – The C Language Mapping specification is aligned with CORBA version 2.0. CORBA is independent of the programming language used to construct clients and implementations. In order to use the ORB, it is necessary for programmers to know how to access ORB functionality from their programming languages.

What does it mean to map a drive?

By mapping a shared drive, you're essentially adding a folder that has already been shared on your network to the list of drives you can access on your own PC. Mapping a shared drive is quite simple as long as you know the shared folder that you want to access.


2 Answers

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.

like image 154
granadaCoder Avatar answered Oct 02 '22 14:10

granadaCoder


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.

like image 36
Justin Avatar answered Oct 02 '22 15:10

Justin