简体   繁体   中英

How can I include a conversion from one database type to another entity type with EF5?

The use case is the following: I have a SQLite database and a SQL Server database that are identical. Some users of the product will use the SQLite version, some the SQL Server version. However, by default, the primary key of SQLite, regardless of your CREATE TABLE statement, will internally be stored as a 64 bit integer and the default for our SQL Server is a 32 bit and sometimes a 16 bit integer.

Because we are talking about large amounts of records, the space needed to store the tables and indexes changes dramatically if we match the datatypes to be 64 bit in both types of databases.

I would like to use a single mapping with Entity Framework, if at all possible, for the entity types. This works for most fields, but not for the primary key fields. Even if the mapping maps to int , and the field in SQLite is an INT , as soon as I try to load the data, I will receive:

InvalidOperationException: The type of the key field 'CustomerId' is expected to be System.Int32 but the value provided is actually of type 'System.Int64'

I understand the reason of the exception: the SQLite driver returns an Int64 . I do not get this error with other fields in the tables (ie, other DDL declarations of INT map to Int32 and do not throw this error).

I was wondering if there is an extension point in the Entity Framework, or another solution, some place where I can simply say: "just cast it to an Int32 , it is safe to do so".

Current ideas involve creating different libraries and dynamic mapping, or some creative generics, but none of the ideas we've had seem satisfiable. Any thoughts?

Answering Matthew's question, table are defined with the following pattern:

-- works
CREATE TABLE [Customer] (
  [CustomerId] INTEGER NOT NULL PRIMARY KEY ON CONFLICT FAIL, 
  [Name] CHAR NOT NULL ON CONFLICT FAIL);

-- works not (throws above error, unless I manually change 
-- type in EDMX to from int to integer and Int32 to Int64)
CREATE TABLE [Customer] (
  [CustomerId] INT NOT NULL PRIMARY KEY ON CONFLICT FAIL, 
  [Name] CHAR NOT NULL ON CONFLICT FAIL);

This is an old question, but I had a similar problem and here's what I did.

I am working with the same entities in both sql server and sqlite using EF6. I was getting the mentioned error when querying using sqlite

cntx.Set<T>().FirstOrDefault(a => a.ActivityDescription == activityDescription); .

My key was created like [VSDebugBreakModeEnterEventArgsId] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT in my sqlite db.

I was able to change the key on the model to Int64 instead of int and that fixed the problem. I didnt have to change anything in my sql server db schema to accommodate this. The entity can be inserted, updated, deleted, and queried using an ef context backed by either sqlite or sql server databases.

Also, this behavior only occurred after I upgraded my ef nugets to EF 6.1.1 from ???. At one point there were 3 different projects using 3 different versions of ef and I decided to upgrade them all to the same version. Thats when the above exception started happening.

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