编写与MySQL中的UUID列匹配的查询的正确方法是什么?

时间:2012-08-09 20:19:11

标签: mysql entity-framework

我有一个应用程序,我将其从Postgres移植到MySQL。没关系为什么。该应用程序使用Entity Framework 4来查询数据库。

由于各种原因,我必须在我的C#代码中使用Guids,将它们保存到数据库,然后根据Guids的已保存值查询数据。我不是很熟悉MySQL&它是如何处理基本上是blob的。

首先,MySQL中没有UUID类型。我必须将它们保存为BINARY(16)值。好的。我已经将列创建为BINARY(16)并将数据写入表中。好。

我的问题是我无法看到Guids的存储值匹配。我编写了一个单元测试,用于将具有已知Guid的数据写入表中,然后尝试检索它。数据很好地进入了数据库,但是当我尝试将其读回时,我没有得到任何行。

这是一个示例表模式:

CREATE TABLE `MyDatabase`.`MyTable` (
    `id`                INT             NOT NULL AUTO_INCREMENT,
    `guid`              BINARY(16)      NOT NULL,
    `applicationId`     INT(11)         NOT NULL,
    `name`              VARCHAR(256)    NOT NULL,
    Description         VARCHAR(256)    NULL,
    SessionTimeout      INT             NOT NULL,
    DomainId            INT             NOT NULL,
    PRIMARY KEY (`id`),
    CONSTRAINT IX_aspnetx_groups UNIQUE ( `applicationId`, `id` )
);

这是实体框架代码:

var g = ( from r in context.MyTable
          where r.guid = id
          select r ).Single();

以下是Entity Framework生成的查询:

SELECT
`Extent1`.`id`, 
`Extent1`.`guid`, 
`Extent1`.`applicationId`, 
`Extent1`.`name`, 
`Extent1`.`Description`, 
`Extent1`.`SessionTimeout`, 
`Extent1`.`DomainId`
FROM `aspnetx_groups` AS `Extent1`
WHERE `Extent1`.`guid` = '81d7de5e-4212-4ff8-b3d4-9f115261971d' LIMIT 2;

执行此操作时,它不返回任何行,导致在我的C#代码中抛出“sequence contains no elements”异常。

我如何使这项工作?

2 个答案:

答案 0 :(得分:1)

在SELECT的WHERE子句中,看起来你正在比较一个BINARY(16)(equals左边的guid)和右边的字符串文字。

要执行有效的比较,我会将该字符串文字转换为BINARY(16),然后将其与guid进行比较。

因此,删除所有短划线字符然后使用UNHEX函数应该可以做到这一点:

WHERE `Extent1`.`guid` = 
  UNHEX(REPLACE('81d7de5e-4212-4ff8-b3d4-9f115261971d','-',''))

为了提高性能,你需要你的查询引用左侧的裸guid列(就像它一样),并且 not 将guid列包装在任何类型的函数中。您希望在谓词的文字侧进行任何转换,因此转换只需在查询开始时执行一次,而不必对表中的每一行进行转换。

答案 1 :(得分:0)

事实证明,我遇到的问题与MySQL Connector / Net包中的Entity Framework连接器的怪癖有关。如果您使用BINARY(16)作为数据库中Guids的数据类型,则需要添加连接字符串设置:

Old Guids=True

一旦将其添加到连接字符串,Entity Framework就会开始发出在插入,更新或比较Guids时真正起作用的代码。

我还得出结论,MySQL中的UUID / Guid支持只是半生不熟,需要一些认真的工作才能使其达到可用状态。