Entity Framework does not convert INTEGER from Firebird to long from C #

1

I'm doing some testing with Entity Framework by mapping and migrating a database from a legacy system.

Scenery

Where I have a table similar to this:

TESTE
-------------------------------------- 
ID     INTEGER NOT NULL,
NOME   VARCHAR(100),
ATIVO  SMALLINT DEFAULT 0 NOT NULL
--------------------------------------

And in my model this:

public class Teste: BaseModel
{
    public virtual string Nome { get; set; }
    public virtual bool Ativo { get; set; }
}

public class BaseModel
{
    public virtual long Id { get; set; }
}

Since my Fluent mapping would be this:

var testeMapper = modelBuilder.Entity<Teste>().ToTable("TESTE");
testeMapper.HasKey(x => x.Id).Property(x => x.Id).HasColumnName("ID");
testeMapper.Property(x => x.Nome).HasColumnName("NOME");
testeMapper.Property(x => x.Ativo).HasColumnName("ATIVO");

Problem

When I run a simple query in this table, I'm surprised by the following error:

  

The type of the key field 'Id' is expected to be 'System.Int64', but the value provided is actually of type 'System.Int32' .

What I understand is because I am using long ( System.Int64 ) in the template and my database the column is of type INTEGER (which it considers System.Int32 ). This does not seem to make much sense, since System.Int32 can easily be set to a System.Int64 . (The opposite would not be enough).

I know that:

  • Changing the type of the Id attribute in my template to int ( System.Int32 ) will work;
  • Changing the type of column ID to BIGINT (which it considers System.Int64 ) will also work;
  • But these two options would not be viable for my case, as:

  • The Id attribute of type long is in class BaseModel which is a system convention, and is long because new tables are being created with ID BIGINT . To outline this the model could not inherit from BaseModel , which would not be the best option.
  • The ID column would give a large maintenance to be converted to BIGINT , since it has contraints and PKs attached to it which makes the job difficult.
  • Question

  • Is there a way to turn this EntityFramework check off?
  • Or is there a setting that allows the template and table to continue this way?
  • asked by anonymous 13.09.2016 / 17:01

    1 answer

    1

    Change your class BaseModel to Generic , see below:

    public class BaseModel<T>
    {
        public virtual T Id { get; set; }
    }
    

    in your class:

    public class Teste: BaseModel<int> // ou long
    {
        public virtual string Nome { get; set; }
        public virtual bool Ativo { get; set; }
    }
    

    The rules for mapping data to Entity Framework are restrictive to the data type of the Table , that it would not be logical to be different, if in your table it is with INTEGER the given in classe is int ( Int32 ) and be for BigInt (Int64 ), if the next tables will be BigInt to classe BaseModel with a type Generic solves this type problem.

    In the Entity Framework you can not turn off verification , this is internal and in my vision would be a big error , would bring more problems than solution, since it follows the standards set in the table settings.

    So, by reaffirming, BaseModel<T> Generic that can have int or long as paramenter of type , and does not influence in itself the settings of your legacy database.

      

    Log Generated INSERT :

      

    For ID to type int or INT32

    Closed connection at 13/09/2016 20:52:24 -03:00    
    Opened connection at 13/09/2016 20:52:24 -03:00    
    Started transaction at 13/09/2016 20:52:24 -03:00
    
    EXECUTE BLOCK ( p0 VARCHAR(50) CHARACTER SET UTF8 = @p0 )  
      RETURNS ("ID" INT) AS BEGIN INSERT INTO "CLIENTE"("NOME") 
      VALUES (:p0) RETURNING "ID" INTO :"ID"; SUSPEND; END
    
    -- @p0: 'BAB' (Type = String, Size = 50)    
    -- Executing at 13/09/2016 20:52:24 -03:00    
    -- Completed in 21 ms with result: FbDataReader    
    Committed transaction at 13/09/2016 20:52:24 -03:00    
    Closed connection at 13/09/2016 20:52:24 -03:00
    

    In this snippet, note that it sends a face of type String 50 to the table.

    -- @p0: 'BAB' (Type = String, Size = 50)
    

    and in that

    RETURNS ("ID" INT)
    

    The return type of ID is int .

      

    For ID of type long or Int64

    Closed connection at 13/09/2016 20:59:53 -03:00
    Opened connection at 13/09/2016 20:59:53 -03:00
    Started transaction at 13/09/2016 20:59:53 -03:00
    
    EXECUTE BLOCK (
    p0 VARCHAR(50) CHARACTER SET UTF8 = @p0
    ) RETURNS (
    "ID" BIGINT)
    AS BEGIN
    INSERT INTO "GENTE"("NOME")
    VALUES (:p0)
    RETURNING "ID" INTO :"ID";
    SUSPEND;
    END
    
    -- @p0: 'abc' (Type = String, Size = 50)
    -- Executing at 13/09/2016 20:59:53 -03:00
    -- Completed in 16 ms with result: FbDataReader
    Committed transaction at 13/09/2016 20:59:53 -03:00
    Closed connection at 13/09/2016 20:59:53 -03:00
    

    in this case the

    RETURNS ("ID" BIGINT)
    

    ID is of type BIGINT (Int64)

    References:

    Note: the switch virtual , is not required in all properties, only in collections and aggregation for Entity Framework

        
    13.09.2016 / 17:39