Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#: Change Retrieval DataType for Entity Framework

I'm trying to convert a project that is currently using a custom DAO framework to using Entity Framework. The system is quite large so changes to the database (a SQL Azure DB if that matters) itself aren't particularly feasible and should be avoided if possible.

The problem is with the ID column. Unfortunately when the system was created, there are some tables that have a bigint datatype, and some that have an int - but the models themselves all come from a base class having a long for the ID. The previous framework was able to handle this situation, but I have been unable to find a way to do it with entity framework.

Below is the most trivial example I can think of:

public class Context : DbContext {
    public IDbSet<Foo> Foos {get;set;}
    public IDbSet<Bar> Bars {get;set;}
}
public abstract class BaseClass {
    public long ID;
}
public class Foo : BaseClass {
    ...
}
public class Bar : BaseClass {
    ...
}
SQL Table: Foo
+-------------+
| id : bigint |
| ...         |
+-------------+
SQL Table : Bar
+-------------+
| id : int    |
| ...         |
+-------------+

When I try to load a Bar model, I get this error:

The 'ID' property on 'BaseClass' could not be set to a 'Int32' value. You must set this property to a non-null value of type 'Int64'.

I'd like to find a way to tell the system that Bar has ints, while Foo has longs. I've tried overriding OnModelCreating in the context and defining HasColumnType for Bar. That gave me a new error:

Schema specified is not valid. Errors:
    (105,12) : error 2019: Member Mapping specified is not valid. The type 'Edm.Int64[Nullable=False,DefaultValue=]' of member 'ID' in type 'Bar' is not compatible with 'SqlServer.int[Nullable=False,DefaultValue=,StoreGeneratedPattern=Identity]' of member 'ID' in type 'CodeFirstDatabaseSchema.Bar'.

It seems to me that if I could only change the expected data type for the ID of BaseClass to int before sending the request to the server, then I should be able to up-convert to a long after I receive the response. Ideally, I'd like to do this on a per-class basis.

Can anyone point me in the right direction?

like image 871
Merwer Avatar asked Mar 07 '12 21:03

Merwer


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr. Stroustroupe.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

Why do we write C?

We write C for Carbon Because in some element the symbol of the element is taken form its first words and Co for Cobalt beacause in some elements the symbol of the element is taken from its first second letters, so that the we don't get confuse.


1 Answers

While you can implicitly cast a bigint to an int in SQL Server, it appears that the Entity framework EDM types (which is really what you're dealing with) doesn't allow an implicit transformation from a 64-bit integer type to a 32-bit integer type.

This is probably for good reason, because you could easily overflow and have values that don't fit in the int fields.

That said, you should have two base classes, one for an int ID and one for a long ID. It's not pretty, but it enforces logic that you definitely want; you won't be able to store values that are larger than what can fit into an int in the database, so why would you want to be able to do it on the code level? The Entity framework is doing the right thing here in not letting you apply that transformation.

like image 86
casperOne Avatar answered Oct 12 '22 10:10

casperOne