Linq到EF guid in where子句总是返回null

时间:2015-09-07 21:15:55

标签: c# entity-framework linq sqlite

我尝试了很多不同的方法,LINQ语句中的“topic”始终为null。在将GUID与SQLite作为数据源进行比较时,是否需要做一些特殊的事情?

    public TopicModel GetTopicModel(Guid id)
    {
        TopicModel topicModel = null;
        using (var context = new onenessEntities())
        {
            var topic = context.Topics.FirstOrDefault(x => x.Id.Equals(id));

            if (topic != null)
            {
                topicModel = new TopicModel
                {
                    Id = topic.Id,
                    Description = topic.Description,
                    Title = topic.Title
                };
            }
        }

        return topicModel;
    }

自动生成的SQL

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[CategoryId] AS [CategoryId], 
[Extent1].[Language] AS [Language], 
[Extent1].[Title] AS [Title], 
[Extent1].[Description] AS [Description], 
[Extent1].[Keywords] AS [Keywords], 
[Extent1].[Version] AS [Version], 
[Extent1].[CurrentPosition] AS [CurrentPosition], 
[Extent1].[Notes] AS [Notes]
FROM [Topic] AS [Extent1]
WHERE ([Extent1].[Id] = @p__linq__0) AND (@p__linq__0 IS NOT NULL) LIMIT 1


-- p__linq__0: '90f8f2c6-31cf-47a1-b8fb-61d5f4130d8f' (Type = AnsiStringFixedLength)

-- Executing at 9/17/2015 2:56:37 PM -05:00

-- Completed in 1 ms with result: SQLiteDataReader

修改: 我已经知道这个问题是由于SQLite将GUID存储为二进制blob。作为一种解决方法,我将数据类型从GUID更改为CHAR(36),现在可以使用LINQ to EF来检索记录。我仍然想看看是否有人可以回答这个原始问题。

3 个答案:

答案 0 :(得分:2)

要解决此问题,请将此附加到连接字符串:

  

; binaryguid =假

如果为true - GUID列以二进制形式存储;否则GUID列存储为文本。我认为这个问题是由EF注入参数的方式引起的(Type = AnsiStringFixedLength)。

使用原始查询(带有执行阅读器的SQLiteCommand)时,使用guid参数的查询仍然可以正常使用binaryguid。避免EF可以让你自己提供。

command.Parameters.Add(new SQLiteParameter(DbType.Guid)
{
    ParameterName = "@id",
    Value = id
});

答案 1 :(得分:1)

我将Id的数据类型更改为CHAR而不是GUID以解决此问题。

答案 2 :(得分:0)

我想知道为where子句x => x.Id.Equals(id)生成了什么SQL?我找到了this链接,它讨论了表达式分析器中的一个错误,如果id恰好是一个可以为空的uniqueidentifier。

建议的解决方法是以这种方式使用Equals:x => Object.Equals(x.Id, id)