如何将字符串解析为UNIQUEIDENTIFIER?

时间:2013-11-19 03:25:17

标签: .net sql-server entity-framework guid entity-framework-6

我正在编写一个实体框架LINQ查询,其中我想将字符串解析为UNIQUEIDENTIFIER(也称为GUID),作为WHERE子句的一部分:

public IEnumerable<User> Find(Guid guid)
{
    return dbContext
        .Users
        .Where(user => Guid.Parse(user.GuidText) == guid);
}

我知道这在SQL中是可行的,因为我已经测试了它:

SELECT *
FROM Users
WHERE CAST(GuidText AS UNIQUEIDENTIFIER) = @guid;

但是,我还没有找到生成CAST部分的方法。我试过了:

  1. (Guid)user.GuidText,它会产生编译错误。
  2. Convert.ToGuid(user.GuidText),但此方法不存在。
  3. Guid.Parse(user.GuidText),但这会导致Entity Framework在翻译LINQ查询时生成错误。
  4. new Guid(user.GuidText),但这会导致Entity Framework在翻译LINQ查询时生成错误。
  5. (Guid)Convert.ChangeType(user.GuidText, typeof(Guid)),但这会导致Entity Framework在翻译LINQ查询时生成错误。
  6. SqlGuid.Parse(user.GuidText),但这会导致Entity Framework在翻译LINQ查询时生成错误。
  7. 我怎样才能做到这一点?我愿意在代码中嵌入SQL作为最后的手段。

3 个答案:

答案 0 :(得分:1)

EF运行时实际上支持从字符串转换为GUID作为强制转换操作,但正如您所发现的那样,目前无法在我们支持的LINQ中表达这一点。

我能想到的最好的解决方法是使用Entity SQL:

var objectContext = ((IObjectContextAdapter)db).ObjectContext;
var query = objectContext.CreateQuery<User>(
  "SELECT VALUE u FROM Context.Users AS u WHERE CAST(u.GuidText AS System.Guid) = @guid", 
  new ObjectParameter("guid", guid));

答案 1 :(得分:0)

以下是 应该通过使用字符串比较而不是GUID比较来生成等效功能的一些代码:

public IEnumerable<User> Find(Guid guid)
{
    var idString = guid.ToString("N");

    return dbContext
        .Users
        .Where(user => user.UserDirectoryUserId
            .Replace("{", String.Empty)
            .Replace("}", String.Empty)
            .Replace("-", String.Empty)
            .Replace(",", String.Empty)
            .Replace("0x", String.Empty)
            .ToLower()
            == idString
        );
}

显然这不是一个理想的解决方案,因为它会产生丑陋的SQL而不是所需的SQL。

答案 2 :(得分:0)

如果你有成熟的理由进行演员表示 - 你可以在你的用户表上创建一个VIEW,并将你的GUID文本转换为UNIQUEIDENTIFIER

SELECT ..., CAST(GuidText AS UNIQUEIDENTIFIER), ...

比在代码中引用视图,您应该能够在没有强制转换的情况下进行比较