代码之家  ›  专栏  ›  技术社区  ›  Alex

LINQ到SQL违反了具有空列的唯一键约束

  •  0
  • Alex  · 技术社区  · 16 年前

    我有下表。当我尝试使用Linq to SQL插入记录时,它可以正常工作,直到我尝试插入用户ID为空的记录为止。当我尝试时,我得到以下错误

    “唯一键约束不能在对象中插入重复键”

    我只想插入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)
    )
    
    4 回复  |  直到 16 年前
        1
  •  1
  •   Daniel Magliola    16 年前

    它似乎更多地与约束本身有关,而不是与LinqToSQL有关。 我不是专家,但唯一约束可能不会让您在这些字段中拥有空值(例如,主键中不能有空值)。

    您是否尝试使用ManagementStudio中的空用户ID执行插入操作,以查看问题是在LINQ端,还是在SQL Server端? 此外,如果它在ManagementStudio中工作,请尝试为Linq打开日志记录,并附加正在运行的实际SQL查询,这将有助于诊断。

        2
  •  0
  •   Cade Roux    16 年前

    所以第一个也是唯一一个插入 NULL UserId 失败?所以您应该能够设置一个简单的repro案例并发布linq代码?

        3
  •  0
  •   Alex    16 年前

    好吧,问题其实不是insert语句。事实上,当用户ID为空时,我不会返回任何记录,因此不会再次插入相同的记录。所以…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?)混合在一起。

        4
  •  0
  •   cdonner    16 年前

    我也总是和空值作斗争,最后在可空类型和不可空类型之间来回转换。还有一个与fks和null相关的问题,我注意到了,当涉及到删除时,您可能会遇到:

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

    推荐文章