从SQL Server表中选择NULL值

时间:2013-08-30 08:14:52

标签: c# sql sql-server asp.net-mvc-4

我正在使用C#和SQL Server

使用ASP.NET MVC 4

我从下表中选择一行数据

CREATE TABLE [dbo].[Mem_Basic] (
[Id]          INT           IDENTITY (1, 1) NOT NULL,
[Mem_NA]      VARCHAR (100) NOT NULL,
[Mem_Occ]     VARCHAR (200) NOT NULL,
[Mem_Role]    VARCHAR (200) NOT NULL,
[Mem_Email]   VARCHAR (50)  NULL,
[Mem_MPh]     VARCHAR (15)  NULL,
[Mem_DOB]     DATE          NULL,
[Mem_BGr]     NCHAR (10)    NULL,
[Mem_WAnn]    DATE          NULL,
[Mem_Spouse]  VARCHAR (75)  NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);

使用以下代码

public MemberBasicData GetMemberProfile(int id)
{
        MemberBasicData mb = new MemberBasicData();
        using (SqlConnection con = new SqlConnection(Config.ConnectionString))
        {
            using (SqlCommand cmd = new SqlCommand("SELECT * FROM Mem_Basic WHERE Id="+id+"", con))
            {
                try
                {
                    con.Open();
                    SqlDataReader reader = cmd.ExecuteReader();
                   if(reader.Read()==true)
                    {
                        mb.Id = (int)reader["Id"];
                        mb.Mem_NA = (string)reader["Mem_NA"];
                        mb.Mem_Occ = (string)reader["Mem_Occ"];
                        mb.Mem_Role = (string)reader["Mem_Role"];
                        mb.Mem_Email = (string)reader["Mem_Email"];
                        mb.Mem_MPh = (string)reader["Mem_MPh"];
                        mb.Mem_DOB = (Convert.ToDateTime(reader["Mem_DOB"]));
                        mb.Mem_BGr = (string)reader["Mem_BGr"];
                        mb.Mem_WAnn = (Convert.ToDateTime(reader["Mem_WAnn"]));
                        mb.Mem_Spouse = (string)reader["Mem_Spouse"];
                   }
                }
                catch (Exception e) { throw e; }
                finally { if (con.State == System.Data.ConnectionState.Open) con.Close(); }
            } 
        }
        return mb;
    }

这显示错误

  

无法将'System.DBNull'类型的对象强制转换为'System.String'。

Mem_EmailMPh ..等有时包含NULL值..如果值为null,我想返回null)。有人请帮助我。

6 个答案:

答案 0 :(得分:3)

如果你做了一些简短的话,你应该为所有其他变量做同样的事情:

 mb.Mem_Email = reader["Mem_Email"] == System.DBNull.Value ? null : (string) reader["Mem_Email"];

答案 1 :(得分:3)

使用像dapper(http://www.nuget.org/packages/Dapper)这样的工具可以为您节省大量的痛苦:

public MemberBasicData GetMemberProfile(int id)
{
    using (var con = new SqlConnection(Config.ConnectionString))
    {
        return con.Query<MemberBasicData>(
            "SELECT * FROM Mem_Basic WHERE Id=@id",
            new { id } // full parameterization, done the easy way
        ).FirstOrDefault();
    }
}

这样做:

  • 确实正确参数化(性能和安全性),但没有任何不便
  • 完成所有实现,为您处理空值(包括参数和列)
  • 是疯狂优化的(基本上,它与自己编写所有代码的速度相同,除了更少的错误)

答案 2 :(得分:2)

除了King King的回答,您可以编写如下代码:

mb.Mem_Email = reader["Mem_Email"] as string;

对于值类型,如果列允许空值,最好将它们映射到C#中的可空值类型,以便此代码reader["Mem_DOB"] as DateTime?起作用

答案 3 :(得分:0)

更改所有列,可能是此

中的NULL
mb.Mem_NA = (string)reader["Mem_NA"];

到那个

mb.Mem_NA = reader["Mem_NA"].ToString();

答案 4 :(得分:0)

处理可空字段:

mb.Mem_Email = System.DBNull.Value.Equals(reader["Mem_Email"])?"":
                                      (string)reader["Mem_Email"];

执行相同的: mb.Mem_MPh,mb.Mem_BGr和mb.Mem_Spouse。

答案 5 :(得分:0)

我并不是说听起来像是一个SQL bigot(这当然意味着我 DO 是为了听起来像一个SQL bigot),但是如果您遵循SQL最佳实践并使用了一个列列表, SELECT *您可以通过在可为空的列上使用COALESCE来解决此问题,

SELECT
  [Id],
  [Mem_NA],
  [Mem_Occ],
  [Mem_Role],
  COALESCE( [Mem_Email], '' ) AS [Mem_Email],
  COALESCE( [Mem_MPh], '' ) AS [Mem_MPh],
  COALESCE( [Mem_DOB], CAST( '1753-1-1' AS DATE ) ) AS [Mem_DOB],
  COALESCE( [Mem_BGr, '' ) AS [Mem_BGr],
  COALESCE( [Mem_WAnn], CAST( '1753-1-1' AS DATE ) ) AS [Mem_WAnn],
  COALESCE( [Mem_Spouse], '' ) AS [Mem_Spouse]
FROM 
  [dbo].[Mem_Basic];

您的C#代码现在可以可靠地处理结果集,而不必考虑离群值了(日期除外;您可能应该检查一下COALESCE中使用的默认值(我使用了SQL的最小允许值)上面示例中的日期变量),并对其进行适当处理。

此外,您可以摆脱c#代码中的finally块。您将连接包装在“使用”块中;超出范围时,它将自动关闭连接(这是“使用”块的目的)。