【问题标题】:LINQ to SQL Violation of UNIQUE KEY constraint with NULL columnLINQ to SQL 违反具有 NULL 列的 UNIQUE KEY 约束
【发布时间】:2009-05-28 02:43:20
【问题描述】:

我有下表。当我尝试使用 LINQ to SQL 插入记录时,它工作正常,直到我尝试插入 UserId 为空的记录。当我尝试时出现以下错误

“UNIQUE KEY 约束不能在对象中插入重复键”

我只尝试插入 1 条记录,表是空的,所以唯一约束绝对没有冲突。

CREATE TABLE [dbo].[QuickViewUserModule](
    [QuickViewUserModuleId] [int] IDENTITY(1,1) NOT NULL,
    [QuickViewModuleId] [int] NOT NULL,
    [UserId] [int] NULL,
    [SortOrder] [tinyint] NOT NULL,
... More key stuff ...
    CONSTRAINT [IX_QuickViewUserModule] UNIQUE NONCLUSTERED  (  
        [UserId] ASC,   
        [QuickViewModuleId] ASC)
)

【问题讨论】:

    标签: .net sql-server linq-to-sql


    【解决方案1】:

    这似乎与约束本身有关,而不是与 LINQ to SQL 有关。 我不是专家,但也许 UNIQUE CONSTRAINT 不会让您在这些字段中有 NULL 值(例如,您不能在主键中有 null 值)

    您是否尝试过在 Management Studio 中使用 NULL UserID 执行 INSERT,以查看问题出在 LINQ 端还是 SQL Server 端? 此外,如果它在 Management Studio 中运行,请尝试为 LINQ 启用日志记录,并附加正在运行的实际 SQL 查询,这将有助于诊断。

    【讨论】:

    • 你如何打开 linq 的日志记录?我只有 express,所以我没有 SQL profiler。
    • 一个 UNIQUE CONSTRAINT 会让你有一个 NULL,但只有一个:sqlmag.com/Article/ArticleID/25259/sql_server_25259.html 在这种情况下,它应该允许多个 NULL,但只能在不同的 QuickViewModuleId 内。
    • @Roux:此错误与约束无关。在 SQL Server 2005 中,您可以根据需要在此表中插入任意数量的带有 NULL user_ids 的行(我实际上尝试过)。 NULL 值被约束忽略。我不知道2000年,这是您引用的旧文章。
    • @Alex: TextWriter tw = Console.Out; db.Log = tw;例如
    【解决方案2】:

    所以NULL UserId 的第一个也是唯一一个插入失败了?所以你应该能够设置一个简单的复制案例并发布 LINQ 代码?

    【讨论】:

      【解决方案3】:

      好的,问题实际上不是插入语句。事实上,当 UserId 为 NULL 时,我没有返回任何记录,因此再次插入相同的记录。所以... SQL Server 做的是正确的事情 :)

      但是,在 LINQ 中处理空值时,我发现了一些奇怪的东西。我不得不更改以下内容

      return (from dm in Context.DesktopModules
              join qvu in Context.QuickViewUserModules on dm.DesktopModuleID equals qvu.QuickViewModuleId
              where qvu.UserId == (userId == Null.NullInteger ? null : (int ?)userId)
              orderby qvu.SortOrder, dm.ModuleName ascending
              select dm).ToList();
      

      到这里

      if(userId == Null.NullInteger)
      {
          return (from dm in Context.DesktopModules
              join qvu in Context.QuickViewUserModules on dm.DesktopModuleID equals qvu.QuickViewModuleId
              where qvu.UserId == null
              orderby qvu.SortOrder, dm.ModuleName ascending
              select dm).ToList();
      }
      else
      {
          return (from dm in Context.DesktopModules
              join qvu in Context.QuickViewUserModules on dm.DesktopModuleID equals qvu.QuickViewModuleId
              where qvu.UserId == userId
              orderby qvu.SortOrder, dm.ModuleName ascending
              select dm).ToList();
      }
      

      当 (int) & (int ?) 混合在一起时,LINQ 似乎不起作用。

      【讨论】:

        【解决方案4】:

        我也总是与空值作斗争,最终在可空类型和不可空类型之间来回转换。我知道还有另一个与 FK 和 NULL 相关的问题,在删除时您可能会遇到:

        http://blogs.msdn.com/bethmassi/archive/2007/10/02/linq-to-sql-and-one-to-many-relationships.aspx

        【讨论】:

        • 很高兴知道这一点!我想我可能还是会级联。我通常也控制开发的数据库端。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-17
        • 1970-01-01
        • 1970-01-01
        • 2011-04-16
        • 1970-01-01
        相关资源
        最近更新 更多