用例如下:我有一个相同的SQLite数据库和一个SQL Server数据库。该产品的某些用户将使用SQLite版本,一些使用SQL Server版本。但是,默认情况下,SQLite的主键,无论您的CREATE TABLE
语句如何,都将在内部存储为64位整数,SQL Server的默认值为32位,有时为16位整数。
因为我们讨论的是大量记录,如果我们在两种类型的数据库中将数据类型匹配为64位,则存储表和索引所需的空间会发生显着变化。
我想使用实体框架的单一映射(如果可能的话),用于实体类型。这适用于大多数字段,但不适用于主键字段。即使映射映射到int
,并且SQLite中的字段是INT
,只要我尝试加载数据,我就会收到:
InvalidOperationException:键字段的类型' CustomerId'应该是System.Int32,但提供的值实际上是' System.Int64'
的类型
我理解异常的原因:SQLite驱动程序返回Int64
。我没有在表中的其他字段中得到此错误(即,INT
的其他DDL声明映射到Int32
并且不会抛出此错误。)
我想知道实体框架中是否有扩展点或其他解决方案,我可以简单地说一些地方:"只需将其转换为Int32
,这样做是安全的#34;
目前的想法涉及创建不同的库和动态映射,或者一些创意泛型,但我们似乎没有任何想法可以满足。有什么想法吗?
回答马修的问题,表格定义如下:
-- 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);
答案 0 :(得分:1)
这是一个老问题,但我遇到了类似的问题,这就是我所做的。
我使用EF6在sql server和sqlite中使用相同的实体。在使用sqlite
查询时,我收到了上述错误 cntx.Set<T>().FirstOrDefault(a => a.ActivityDescription == activityDescription);
。
我的密钥在我的sqlite db中创建了[VSDebugBreakModeEnterEventArgsId] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT
。
我能够将模型上的密钥更改为Int64
而不是int
,从而解决了问题。我没有必要更改我的SQL Server数据库架构中的任何内容以适应这一点。可以使用sqlite或sql server数据库支持的ef上下文插入,更新,删除和查询实体。
此外,这种行为只发生在我将我的ef nugets从???升级到EF 6.1.1之后。有一次,有3个不同的项目使用3个不同版本的ef,我决定将它们全部升级到相同的版本。这就是上述异常开始时的情况。