1

我有两张表,为简单起见,假设它们是这样定义的

Stack 
{
    ID       int  Primary Key
    Name     varchar(255), not null
}

User
{
    ID           int  Primary Key
    Name         varchar(255), not null
    Stack_ID     int, Foreign Key to Stack.ID nulls are allowed
}

我用于插入用户的存储过程看起来像这样

CREATE PROCEDURE usp_insertUser
    @id int,
    @name varchar(255),
    @stackID int
AS
    INSERT INTO User (ID, Name, Stack_ID) VALUES (@id, @name, @stackID)
GO

在我的模型层我的用户类中,我使用可空值来保存 StackID

public class User
{
     public int ID {get; set;}
     public string Name {get; set;}
     int? Stack_ID {get; set;}
}

我认为我的数据访问层非常标准,但我遇到了麻烦,我的 InsertUser 方法看起来与此类似

 public void InsertUser(User entity)
 {
     ...
     using (SqlCommand command = new SqlCommand())
     {
         command.Connection = conn;
         command.CommandType = System.Data.CommandType.StoredProcedure;
         command.CommandText = "usp_insertUser";

         command.Parameters.AddWithValue("@id", entity.ID);
         command.Parameters.AddWithValue("@name", entity.Name);
         command.Parameters.AddWithValue("@stackID", entity.Stack_ID);
         conn.Open();
         ...
         //real stored proc returns the id of the item inserted so i use a reader
         SqlDataReader reader = command.ExecuteReader();
         ....
    }
 }

我的问题是,当我将 User.Stack_ID 保留为 null 时,它不会在数据库中插入 null,而是出现错误,说 @stackID 是预期的,但不存在。为什么我不能直接将这个可为空的 int 插入数据库?

另外,有没有一种方法可以让我从数据库中读取这个可能的 null int ?

当我这样做时,我认为这会起作用。

User.Stack_ID = (int?)reader["Stack_ID"];

这显然行不通,我必须做一些草率的事情

try {
   User.StackID = (int)reader["Stack_ID"];
}
catch {
   User.StackID = null;
}

使用这些 Nullable 类型的任何帮助将不胜感激。抱歉,对于菜鸟问题​​,过去当我有整数并想要一个空值或 w/e 我会将它们设置为 -1 或 0 或其他东西时,当它们是外键时这不起作用:-(

4

3 回答 3

2
command.Parameters.AddWithValue("@stackID", entity.Stack_ID ?? (object) DBNull.Value);

要读取空值,您可以这样做:

User.StackID = reader.Field<int?>("Stack_ID");

这使用了Field扩展方法。来自 MSDN:

Field 方法支持将列作为可空类型访问。如果 DataSet 中的基础值为 [DBNull.]Value,则返回的可为 null 类型将具有 null 值。

于 2012-07-10T18:29:12.573 回答
0

有一种特殊的类型称为DBNull将空值插入数据库。

尝试

command.Parameters.AddWithValue("@stackID", entity.Stack_ID.HasValue ? entity.StackId : DBNull.Value);
于 2012-07-10T18:29:42.833 回答
0

最简单的方法是使用as.

int? myNullableInt = reader["Stack_ID"] as int?;

需要注意的是,如果reader["Stack_ID"]是不同的数据类型(例如字符串、十进制等),那么您将得到 null 而不是异常。

编辑:至于插入到数据库中,如果使用 插入command.Parameters.Add,则不需要更改数据类型,它将支持可为空的值。

于 2012-07-10T18:30:16.990 回答