在C#中使用“as”,“is”,“DBNull”,ToString()的优点和缺点

时间:2011-10-12 11:38:03

标签: c# .net ado.net

从ExecuteReader读取数据时。它返回IDataReader中的数据。当我想将这些数据填充到我的实体中时,我将在大多数情况下将Non Nullable值分配给Nullable类型或Non Nullable类型,例如:

int id;
string name;
int? age;
byte[] image;

example e = new example();
e.id = (int)dr["id"]; //unbox
e.name = dr["name"].ToString() //will result in empty string if dr["name"] is DBNull
e.name = dr["name"] is DBNull ? null : dr["name"].ToString();
e.age = dr["age"] as int?; // way 1
e.age = dr["age"] is DBNull ? null : (int?)dr["age"]; //way 2
e.image = dr["image"] as byte?;

修改

如果id是表的主键并且是NonNullable。但它正在另一个表中使用,其中该键可能是NULL然后应该是什么方法。该实体是否应该变为NULL或者应该抛出异常。

5 个答案:

答案 0 :(得分:2)

如果对象引用为null,则is运算符始终返回false,因为没有可用于检查其类型的对象。

if (o is Employee) {
Employee e = (Employee) o;
// Use e within the ‘if’ statement.
}

as运算符的工作方式与cast类似,但as运算符永远不会抛出异常。相反,如果无法转换对象,则结果为null。

Employee e = o as Employee;
if (e != null) {
// Use e within the ‘if’ statement.
}

查看更多:C# is and as operators

答案 1 :(得分:1)

如果您确定结果类型且不能为null:

(int)dr["id"]

如果结果可以为null并且您知道类型:

dr["age"] as int?;
dr["age"] as int? ?? -1; // default value

如果结果不能为空且您不知道类型:

Convert.ToInt32(dr["age"]);

如果结果可以为null并且您不知道类型:

object age = dr["age"]; // can be short, int, etc
!Convert.IsDBNull(age) ? Convert.ToInt32(age) : -1;

答案 2 :(得分:0)

我的作业看起来像这样:

e.id    = (int)dr["id"]; //unbox
e.name  = dr["name"]  as string; // String if string, null if DbNull
e.age   = dr["age"]   as int?;
e.image = dr["image"] as byte?;

as运算符最适合引用类型(例如字符串或nullables),因为如果我正在转换的对象是DbNull,它将返回null。这与手动检查完全相同,但更简洁易懂。

答案 3 :(得分:0)

查看this question的答案,了解一些针对您的问题的通用辅助函数的好例子。

答案 4 :(得分:0)

在(评论)中,您要求提供有关我的短篇评论的更多信息;我试图提出的一点是,这本质上是一个已经解决的问题,从复杂和功能丰富的ORM(NHibernate,实体框架,LLBLGenPro)到中间地带(LINQ),有一系列工具可以提供帮助。 -to-SQL等),通过简单(但非常有效)的微ORM(dapper-dot-net,Peta.Poco,Simple.Data)。

dapper-dot-net是支持stackoverflow / stackexchange的(免费提供的OSS)微ORM。它基于直接从返回的列名映射到成员名称(字段或属性)的简单方法,这样的用法很简单:

var connection = ... // an open connection
int id = ...  // a record to fetch
var singleItem = connection.Query<example>(
    "select * from example where id = @id", new {id}).Single();

int customerId = ...
var orders = connection.Query<Order>(
    "select * from Orders where Status = 'Open' and CustomerId = @customerId",
    new {customerId}).ToList();

其中example是代码中的类型,成员为nameid等。它负责所有繁重的工作:

  • 将输入映射到参数(请参阅@id@customerId,以及如何提供这些值)
  • 以非常优化的方式将返回的记录物化为对象
  • 其他一些技巧,如水平多重映射,多网格映射,自动IN处理等

这意味着您没有担心nullDBNullNullable<T>等详细信息,因为dapper已经为您处理了所有这些问题,并且(感谢一些IL voodoo)在运行时和在自己编写实现代码一样快。