Entity Framework does not convert Firebird INTEGER to C#long

Asked

Viewed 107 times

1

I am doing some tests with Entity Framework mapping and migrating a database of a legacy system.

Setting

Where I have a table similar to that:

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

And in my model that:

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 executing a simple query in this table, I am 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'.

Which, from what I understand, is why I’m using long(System.Int64) in the template and my database the column is of the type INTEGER (that he considers System.Int32). Which doesn’t seem to make much sense, because the System.Int32 can easily be set in a System.Int64 (The other way around).

I know that:

  1. If you change the attribute type Id on my model for int (System.Int32) will work;
  2. If you change the column type ID for BIGINT (that he considers System.Int64) will also work;

But these two options would not be viable in my case, because:

  1. The Attribute Id of the kind long is in the class BaseModel which is a system convention, and is long because the new tables are being created with ID BIGINT. For this outline the model could not inherit from BaseModel, which would not be the best option.
  2. The ID column would give a great upkeep to be converted to BIGINT, that’s right contraints and PKs linked to it which makes the work difficult.

Question

  1. Is there any way to turn off this Entityframework check?
  2. Or is there any configuration that allows the model and table to continue this way?

1 answer

1

Change your class BaseModel for 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 to map the data to Entity Framework are restricted to the data type of the Table, that it would not be logical to be different, if in your table is with INTEGER the data in classe is int(Int32) and be it BigInt(Int64), if the next tables will be with Bigint to classe BaseModel with a guy Generic solves this type problem.

In the Entity Framework there’s no way turn off the check, This is internal and in my view would be a great error, would bring more problems than solution, since it follows the standards set in the table settings.

So, reaffirming, make a BaseModel<T> Generic that you may have int or long as type parameter, and not influencing 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 section, note that he sends a message of the type String size 50 to the table.

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

and in that

RETURNS ("ID" INT)

the type of return 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 that case the

RETURNS ("ID" BIGINT)

the ID is the type BIGINT (Int64)


References:

Observing: the modifier virtual, not required in all properties, only in collections and aggregation for Entity Framework

  • Sure I understood your alternative and I’m already implementing here in my tests, and it seems to work accordingly. Just one more question, as I understood the functioning of this check it does a query in the table metadata and checks if the types are matching. And can’t this be disabled for production? To avoid overhead in the query? I believe this only occurs when starting Context, but even so it seems unnecessary for production environment!

  • It uses corresponding patterns and types between database and classes, at the time of the Insert it sends the type and errors can occur in the translation. Until version 6.1.3 it works like this, particular of the ORM. NEVER seen setting to disable, nowhere, I honestly think it does not have. I will generate an Insert Log, and add in the answer, as soon as you enter the pc I am in the cell.

  • @Fernando I put the two logs one with Insert of the ID type int and the other Long. it’s time for the Insert, Update e Delete he sends vestments to the bank that has types and then the problem can occur if it is not the respective one. In fact, the Firebird installed is the one who makes this generation of SQL.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.