我正在编写一个实体框架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
部分的方法。我试过了:
(Guid)user.GuidText
,它会产生编译错误。Convert.ToGuid(user.GuidText)
,但此方法不存在。Guid.Parse(user.GuidText)
,但这会导致Entity Framework在翻译LINQ查询时生成错误。new Guid(user.GuidText)
,但这会导致Entity Framework在翻译LINQ查询时生成错误。(Guid)Convert.ChangeType(user.GuidText, typeof(Guid))
,但这会导致Entity Framework在翻译LINQ查询时生成错误。SqlGuid.Parse(user.GuidText)
,但这会导致Entity Framework在翻译LINQ查询时生成错误。我怎样才能做到这一点?我愿意在代码中嵌入SQL作为最后的手段。
答案 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), ...
比在代码中引用视图,您应该能够在没有强制转换的情况下进行比较