我将在实体集合中获取结果。我不只需要IDataReader对象。因此,考虑到我没有大量参数并且SP返回了许多数据列,因此应该回答上述问题。
请提供理由。
一些可能是
拖放到DBML设计器,然后通过linq调用它到sql。这是非常好的。但这也为DBML生成了大量代码。越简单越好。
通过执行ExecuteReader
获取IDataReader,然后将IDataReader传递给工厂以创建它的对象。好又简单。但需要大量编码。返回的每列都需要以下内容。
int nameIndex = dataReader.GetOrdinal("Name"); if (!dataReader.IsDBNull(nameIndex)){ myObject.Name = dataReader.GetString(nameIndex); }
还有其他更简单的选择吗?
更新
@ Heinzi的答案简化了处理结果的过程。还有更好的方法来处理大量参数吗?
答案 0 :(得分:3)
如果你想坚持使用DataReader,你可以通过在IDataReader上编写扩展方法来保存一些代码,即类似这样的东西(未经测试):
public static T GetValue<T>(this IDataReader reader, string field, T defaultValue)
{
int index = reader.GetOrdinal(field);
if (reader.IsDBNull(index)) {
return defaultValue;
} else {
return (T)(reader[name]);
}
}
这会将您的工厂代码减少到
myObject.Name = dataReader.GetValue<string>("name", Nothing)
当然,这种扩展方法的无数变体都是可能的(有或没有defaultValue,目标字段作为ref参数传递,以获得与代码完全相同的行为等)。
否则,您可以使用DataSet而不是DataReader,其中已存在这样的扩展方法。您可以像这样创建DataSet(而不是执行myCommand.ExecuteReader
):
var dataSet = new DataSet();
var adapter = new SqlDataAdapter();
adapter.SelectCommand = myCommand;
adapter.Fill(dataSet);
var table = dataSet.Tables[0];
然后,您可以使用DataRowExtensions.Field:
访问您的数据myObject.Name = table.Field<string>("name");
myObject.Age = table.Field<int?>("age") ?? 30; // default value if DBNull