C# 从SQL Server表中选择空值
我正在使用C和SQL Server使用ASP.NET MVC 4 我正在从下表中选择一行数据C# 从SQL Server表中选择空值,c#,sql,sql-server,asp.net-mvc-4,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, [M
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_电子邮件,英里/小时。。etc有时包含空值。。如果值为null,我希望返回null。任何人都可以帮助我。只要简短地说一下,如果你应该对所有其他变量也这样做:
mb.Mem_Email = reader["Mem_Email"] == System.DBNull.Value ? null : (string) reader["Mem_Email"];
在这里,您可以使用像dapper这样的工具来避免严重的疼痛: 它所做的事情: 对性能和安全进行正确的参数化,但不会带来任何不便 执行所有具体化,为您处理参数和列中的空值 基本上是疯狂优化的,它的速度与自己编写所有代码的速度相当,只是出错的次数更少
对所有列进行更改,该值可能为空
mb.Mem_NA = (string)reader["Mem_NA"];
到那
mb.Mem_NA = reader["Mem_NA"].ToString();
除King的答案外,您还可以编写如下代码:
mb.Mem_Email = reader["Mem_Email"] as string;
对于值类型,如果列允许空值,那么最好将它们映射到C中的可空值类型,这样代码读取器[Mem_DOB]就可以作为DateTime?works处理可为空的字段:
对以下对象执行相同的操作:
mb.Mem_MPh、mb.Mem_BGr和mb.Mem_配偶。我并不是想让自己听起来像个SQL偏执狂,这当然意味着我是想让自己听起来像个SQL偏执狂,但是如果您遵循SQL最佳实践,使用列列表而不是选择*的话,您可以通过对可为空的列进行合并来解决此问题,因此:
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块。将连接包装在using块中;当您超出使用块的范围时,它将自动关闭连接。与您的问题无关,因为您有下面的答案,但您的try、catch和finally都是多余的。捕获和抛出是毫无意义的,它将以您实现堆栈跟踪的方式截断堆栈跟踪,最后是关闭连接,即使您使用using语句已经可以处理了。使用连接器或ORM在这里会有很大帮助。就我个人而言,当我听到C和SQL Server时,我认为是实体框架,但有很多替代方案this@Parvathiiiii上面的代码显示了如何使用此函数返回模型。正是这样。基本上,查询方法通过IEnumerable(即每行)将找到的每一行具体化为T的一个实例;从那里我们可以使用LINQ,如果我们愿意的话,所以第一个默认值可以让我们从IEnumerable到T。
mb.Mem_Email = System.DBNull.Value.Equals(reader["Mem_Email"])?"":
(string)reader["Mem_Email"];
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];