问题 SQLite Entity Framework 6提供程序如何处理Guids?


我将我们产品的数据库从另一个支持Guids的产品移植到SQLite。众所周知,SQLite不支持Guids。我已经从我的数据库(数据库优先)创建了一个实体框架6模型,我需要从C#构建一个查询,将Guid与从代码传递的Guid进行比较。

问题是我找不到任何关于SQLite实体框架提供程序如何处理Guids的文档。网络搜索也找不到对我有用的东西。关于在SQLite中使用Entity Framework的问题。

任何人都可以指向我的文档,或者告诉我如何通过EF6模型在SQLite数据库中使用Guids?


7260
2017-12-03 18:37


起源

SQLite没有显式列类型GUID,但存储类型为affinity的类型 BLOB 工作得非常好。不太了解实体框架,但似乎类型转换器(除了枚举)将仅在EF 7中。但GUID具有来自字节数组等的CTor,因此它可能非常简单。 - peterchen
我将它们作为BLOB存储在我的模型中,但是,我有一个问题。代码有一个类似于“ID == Guid('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')的表达式,它会引发异常,因为数据库中的ID类型是 Byte[] 而右边的东西是一个 Guid。有问题的代码必须在我们的客户端(我正在使用的代码)上运行SQLite,在我们的服务器上运行,数据库是SQL Server。表达式字符串不能更改。我必须在SQLite端做一些事情才能使比较工作。我只是不知道是什么。这就是我正在寻找文档的原因。 - Tony Vitabile
在SQLite中,您可以覆盖Guid()函数: sqlite.org/c3ref/create_function.html (不知道通过EF如何工作) - peterchen
'Guid()'函数不能在SQLite中运行。它在SQLite实体框架提供程序中运行,以将字符串转换为Guid。然后,提供程序发出SQL查询,将列中的值与Guid进行比较。问题是EF提供程序不喜欢表达式,因为EF中的列类型是 byte[],但被比较的东西是一个 Guid.  我似乎无法找到任何文档,缺乏Guid支持正在扼杀我。 - Tony Vitabile
你找到了解决方案吗?我现在遇到同样的问题...... - Daniel Sklenitzka


答案:


似乎这在1.0.95中得到了解决,但在1.0.97再次被打破。解决方案是将连接字符串上的BinaryGUID属性设置为true并设置以下环境变量(在建立连接之前)

Environment.SetEnvironmentVariable( “AppendManifestToken_SQLiteProviderManifest”, “; BinaryGUID =真;”);

数据源= c:\ mydb.db;版本= 3; BinaryGUID = True;

https://www.connectionstrings.com/sqlite/


10
2017-07-07 22:35



我正在使用1.0.97,但设置环境变量实际上是为了我。我明白了 System.Data.Entity.Core.ProviderIncompatibleException : The provider did not return a ProviderManifest instance. 和一个内在的例外 System.ArgumentException : An entry with the same key already exists.。但是,只更改连接字符串就可以了。 - Thorarin
伟大的帖子!这解决了我使用1.0.99和Entity Framework 6的问题 - RichTurner
配置文件中的BinaryGUID = True是我需要做的全部。 - CrusherJoe
BinaryGUID今天默认开启。我被迫禁用它以便能够进行查询。 - SeriousM


我终于得到了这个问题的答案。

我的问题是SQLite Entity Framework 6提供程序不能正确处理代码中的文字Guids到SQL。也就是说,形式的Linq表达式

context.MyEntity.Where( x => x.GuidColumn == new Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") )

获取转换为以下SQL:

SELECT GuidColumn, Column1, Column2, . . . Column n
FROM MyEntity AS Extent1
WHERE Extent1.GuidColumn = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

这是错误的,因为存储在列中的值是一个字节数组。

根据 关于SQLite站点的这个问题报告事实证明,SQLite团队认为这是提供程序中的一个错误,他们正在努力在1.0.95.0版本中修复它。我不知道什么时候会发布,但至少他们认为这是一个问题并且要解决它。


3
2018-01-08 18:37



这很糟糕......由于这个问题,我们决定将GUID存储为字符串 - DarkWalker
虽然我不再在该公司工作并且不再能访问该代码库,但我认为我们所做的是将Guid放入Guid变量并与之进行比较。我记得,这是正确处理的。 - Tony Vitabile