我正在使用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_Email
,MPh
..等有时包含NULL
值..如果值为null,我想返回null)。有人请帮助我。
答案 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)
更改所有列,可能是此
中的NULLmb.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块。您将连接包装在“使用”块中;超出范围时,它将自动关闭连接(这是“使用”块的目的)。