如何将字符串解析为UNIQUEIDENTIFIER?

时间:2021-11-11 19:22:13

I'm writing an Entity Framework LINQ query in which I want to parse a string into a UNIQUEIDENTIFIER (aka GUID) as part of the WHERE clause:

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

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

I know this is possible in SQL because I've tested it:

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

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

However, I haven't found a way to generate the CAST part. I've tried:

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

  1. (Guid)user.GuidText, which generates a compiler error.
  2. (Guid)user.GuidText,它会生成编译器错误。
  3. Convert.ToGuid(user.GuidText), but this method doesn't exist.
  4. Convert.ToGuid(user.GuidText),但此方法不存在。
  5. Guid.Parse(user.GuidText), but this causes Entity Framework to generate an error when it translates the LINQ query.
  6. Guid.Parse(user.GuidText),但这会导致Entity Framework在转换LINQ查询时生成错误。
  7. new Guid(user.GuidText), but this causes Entity Framework to generate an error when it translates the LINQ query.
  8. 新的Guid(user.GuidText),但这会导致Entity Framework在转换LINQ查询时生成错误。
  9. (Guid)Convert.ChangeType(user.GuidText, typeof(Guid)), but this causes Entity Framework to generate an error when it translates the LINQ query.
  10. (Guid)Convert.ChangeType(user.GuidText,typeof(Guid)),但这会导致Entity Framework在翻译LINQ查询时生成错误。
  11. SqlGuid.Parse(user.GuidText), but this causes Entity Framework to generate an error when it translates the LINQ query.
  12. SqlGuid.Parse(user.GuidText),但这会导致Entity Framework在转换LINQ查询时生成错误。

How can I achieve this? I'm willing to embed SQL in the code as a last resort.

我怎样才能做到这一点?作为最后的手段,我愿意在代码中嵌入SQL。

3 个解决方案

#1


1  

EF runtime actually supports converting from a string to a GUID as a cast operation, but as you find out there is currently no way of expressing this in LINQ that we support.

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

The best workaround that I can think of is to use Entity SQL:

我能想到的最好的解决方法是使用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));

#2


0  

Here's some code that should produce the equivalent functionality by using a string comparison instead of a GUID comparison:

这里有一些代码应该通过使用字符串比较而不是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
        );
}

Obviously this isn't an ideal solution since it will generate ugly SQL rather instead of the desired SQL.

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

#3


0  

in case you have a mature reason for doing the cast - you can create a VIEWbased on your User table and convert your GUID text to UNIQUEIDENTIFIER

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

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

Than refering the view in your code you should be able to do the comparison without a casting

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

#1


1  

EF runtime actually supports converting from a string to a GUID as a cast operation, but as you find out there is currently no way of expressing this in LINQ that we support.

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

The best workaround that I can think of is to use Entity SQL:

我能想到的最好的解决方法是使用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));

#2


0  

Here's some code that should produce the equivalent functionality by using a string comparison instead of a GUID comparison:

这里有一些代码应该通过使用字符串比较而不是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
        );
}

Obviously this isn't an ideal solution since it will generate ugly SQL rather instead of the desired SQL.

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

#3


0  

in case you have a mature reason for doing the cast - you can create a VIEWbased on your User table and convert your GUID text to UNIQUEIDENTIFIER

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

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

Than refering the view in your code you should be able to do the comparison without a casting

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