【问题标题】:LINQ to SQL Insert Failing because of Join由于加入,LINQ to SQL 插入失败
【发布时间】:2010-07-24 14:43:04
【问题描述】:

我的数据库中有两个表UsersHealthMonitor。在HealthMonitor 表中,我有一个UserID 字段映射到Users 表中的ID 字段。

到目前为止非常简单......

我将HealthMonitor 表中的UserID 字段保留为“Nullable”,这样如果没有当前用户登录,我可以让系统将NULL 值插入表中... IE:如果出现错误被抛出给未经身份验证的用户。

问题是当我尝试将 NULL 插入该 UserID 字段时插入失败。

仅供参考:删除关系也可以解决问题,但我知道这可能不是完成任务的最佳方式

编辑:

在重新应用关系并确保 UserID 可以为空后,它现在似乎可以工作了...但是该值插入为 0 而不是 null

    Public Sub AddException(ByVal ex As Exception, Optional ByVal notes As String = Nothing) Implements IHealthMonitorService.AddException
        Dim exception As HealthMonitor = New HealthMonitor
        Dim userID As Integer = Nothing
        If HttpContext.Current.User.Identity.IsAuthenticated Then userID = Authentication.CustomAuthentication.RetrieveAuthUser.ID

        Dim DataConverter As Utilities.DataConverters = New Utilities.DataConverters
        Dim InformationHelper As Utilities.InformationHelper = New Utilities.InformationHelper

        With exception
            .DateTime = DateTime.Now
            .Exception = ex.ToString
            .Message = ex.Message
            .Notes = notes
            .ShortMessage = If(ex.Message.Length > 50, ex.Message.Substring(0, 50), ex.Message)
            .Source = ex.Source
            .StackTrace = ex.StackTrace
            .Url = HttpContext.Current.Request.Url.ToString()
            .UserID = userID
            .UserIP = DataConverter.IPAddressToNumber(InformationHelper.GetUserIP)
            .UserOS = InformationHelper.GetUserOS()
            .UserBrowser = InformationHelper.GetUserBrowser()
        End With

        _HealthMonitorRepository.AddException(exception)
    End Sub

我在这里遗漏了什么吗?可以插入为NULL

编辑:

好吧,所以我撒了一点谎。我仍然收到错误

    Public Sub AddException(ByVal exception As HealthMonitor) Implements IHealthMonitorRepository.AddException
        dc.HealthMonitors.InsertOnSubmit(exception)
        dc.SubmitChanges()  ''# ERROR HERE
    End Sub

INSERT 语句与 FOREIGN KEY 约束“FK_un_HealthMonitor_un_Users”冲突。冲突发生在数据库“UrbanNow”、表“dbo.un_Users”、列“ID”中。 声明已终止。

这是桌子

/****** Object:  Table [dbo].[un_HealthMonitor]    Script Date: 07/24/2010 10:48:39 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[un_HealthMonitor](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [UserID] [int] NULL,
    [Exception] [nvarchar](4000) NULL,
    [Url] [nvarchar](2048) NULL,
    [Source] [nvarchar](4000) NULL,
    [ShortMessage] [nvarchar](50) NULL,
    [Message] [nvarchar](4000) NULL,
    [StackTrace] [nvarchar](4000) NULL,
    [UserIP] [nvarchar](50) NULL,
    [UserBrowser] [nvarchar](50) NULL,
    [UserOS] [nvarchar](50) NULL,
    [UserIsMoblie] [bit] NULL,
    [DateTime] [datetime2](0) NULL,
    [Notes] [nvarchar](4000) NULL,
 CONSTRAINT [PK_un_HealthMonitor] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[un_HealthMonitor]  WITH CHECK ADD  CONSTRAINT [FK_un_HealthMonitor_un_Users] FOREIGN KEY([UserID])
REFERENCES [dbo].[un_Users] ([ID])
GO

ALTER TABLE [dbo].[un_HealthMonitor] CHECK CONSTRAINT [FK_un_HealthMonitor_un_Users]
GO

【问题讨论】:

  • 与其让该字段为 Nullable,不如使用一个触发器用一个已知值('N/A' 或 0 或等效值)填充它。
  • 触发 - 呸。如果是这种情况,我可以通过 LINQ 提交一个“0”值,但它仍然失败,因为用户表中没有关联的“0”记录
  • @JNK,当关系的另一端没有任何内容时,Null 是正确的值。采用这样的解决方法将是一种耻辱。 @rockinthesixstring,您在使用 VS 吗?您是否在 .dbml 设计器中检查了该属性是否标记为 Nullable?也许它只是被错误地导入了。
  • 我没有签入设计器。我马上去看。
  • 似乎当我重建它并检查以确保 UserID 为 Nullable 时,它​​现在可以工作了。我已经编辑了我的问题,因为值是“0”而不是“NULL”

标签: sql-server linq-to-sql join


【解决方案1】:

成功了!!!

所以基本上在我的服务层中我有......

    Public Sub AddException(ByVal ex As Exception, Optional ByVal notes As String = Nothing) Implements IHealthMonitorService.AddException
        Dim exception As HealthMonitor = New HealthMonitor
        Dim userID As Integer = Nothing
        If HttpContext.Current.User.Identity.IsAuthenticated Then userID = Authentication.CustomAuthentication.RetrieveAuthUser.ID

        Dim DataConverter As Utilities.DataConverters = New Utilities.DataConverters
        Dim InformationHelper As Utilities.InformationHelper = New Utilities.InformationHelper

        With exception
            .DateTime = DateTime.Now
            .Exception = ex.ToString
            .Message = ex.Message
            .Notes = notes
            .ShortMessage = If(ex.Message.Length > 50, ex.Message.Substring(0, 50), ex.Message)
            .Source = ex.Source
            .StackTrace = ex.StackTrace
            .Url = HttpContext.Current.Request.Url.ToString()
            .UserID = userID
            .UserIP = DataConverter.IPAddressToNumber(InformationHelper.GetUserIP)
            .UserOS = InformationHelper.GetUserOS()
            .UserBrowser = InformationHelper.GetUserBrowser()
        End With

        _HealthMonitorRepository.AddException(exception)
    End Sub

问题在于,当我将userID 发送到异常对象时,它正在向数据库发送0(零)。这是解决方案

        Dim userID As Integer? = Nothing ''# (?) makes the integer nullable.

【讨论】:

    【解决方案2】:

    为确保您有一个用户并因此不违反外键,您可以执行以下操作:

    `Public Sub AddException(ByVal exception As HealthMonitor) Implements IHealthMonitorRepository.AddException
        ' take what you need from exception to Create a User
        User user = new User{Populate properties here}
        dc.Users.InsertOnSubmit(user)   
        dc.HealthMonitors.InsertOnSubmit(exception)
        dc.SubmitChanges()  ''# ERROR HERE
    End Sub'
    

    如果需要,您可以通过这种方式创建用户。

    或者您可以为用户进行存在性检查。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    相关资源
    最近更新 更多