【问题标题】:Search uniqueidentifier value in SQL Server 2008 table在 SQL Server 2008 表中搜索 uniqueidentifier 值
【发布时间】:2010-07-05 05:54:10
【问题描述】:

我在 SQL Server 2008 中有一个带有 uniqueidentifier 字段的表。

在我的应用程序(C#、WPF)中,我有一个文本框,用于通过 GUID 搜索一些数据,用户可以通过键入、ctrl+v 等输入 guid,因此他/她可能会出错。

使用 linq2sql 忽略空格、“-”...任何其他字符通过此字段进行搜索的最佳和最快方法是什么?

var d = from status in dc.FolderStatus.Where(status => status.Date <= DateTime.Now 
                    && status.Folder.TapeCode.ToString().Replace("-", "") == tapeCode.ToUpper().Replace("-", "").Replace(" ", "")
                    )

TapeCode 在 SQL Server 2008 中是 uniqueidentifier,在 dbml 文件中是 Guid。还好吗?

【问题讨论】:

  • 请不要在标题中重复 (C#) 等标签。只需将它们留在标签中即可。
  • 代理键的第一条规则是什么?永远不要将其价值暴露给最终用户!

标签: c# sql linq-to-sql search guid


【解决方案1】:

不,这将非常慢(它必须进行表扫描,将每个标识符转换为字符串并比较字符串)。相反,您必须将输入字符串转换为 Guid 并进行比较:

tapeCode = Regex.Replace(tapeCode, "[^0-9a-zA-Z]+", "");
Guid id = Guid.Parse(tapeCode);
var d = from status in dc.FolderStatus
        where status.Date <= DateTime.Now 
           && status.Folder.TapeCode == id
        select status;

(请注意,Guid.Parse 方法接受 32 个不带破折号的十六进制数字作为有效输入)。

【讨论】:

  • (注意 Guid.Parse 是在 .NET 4 中引入的。在此之前您必须调用构造函数。)
  • @Jon: 哦哦哦,这就是为什么我在 Reflector 中找不到它(看看它是否支持 32 位十六进制数字格式),我以为我快疯了 :)
【解决方案2】:

如果它是 SQL 中的 uniqueidentifier 字段,我希望在 LINQ to SQL 中获得本机支持。我相信你应该能够做到:

Guid tapeCode = new Guid(text);
var d = from status in dc.FolderStatus
        where status.Date <= DateTime.Now && status.Folder.TapeCode == tapeCode
        select ...;

当然,如果text 不代表有效的 GUID,这将引发异常。如果您使用的是 .NET 4,则可以像解析整数等一样使用 Guid.TryParse

Guid tapeCode;
if (Guid.TryParse(text, out tapeCode))
{
    var d = from status in dc.FolderStatus
            where status.Date <= DateTime.Now &&
                  status.Folder.TapeCode == tapeCode
            select ...;
}
else
{
    // Handle invalid input
}

【讨论】:

    【解决方案3】:

    您不应该尝试在 SQL 字段上执行 .Replace,因为这实际上会在服务器上执行,这非常慢。

    您应该对传入您的方法的数据进行处理。

    public void GetFoo(string guid)
    {
         string sqlGuid = guid.ToString().Trim().Replace("-", "");
    
         var d = from status in dc.FolderStatus.Where(status => status.Date <= DateTime.Now &&
                                                                status.Folder.TapeCode == sqlGuid);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-15
      • 2011-05-01
      • 2014-02-10
      • 2011-06-10
      • 2012-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多