升级EnterpriseLibrary.Data至5.0.414.0后遇数据源类型无效错误求助
解决Enterprise Library Data 5.0升级后数据源绑定无效问题
升级Microsoft.Practices.EnterpriseLibrary.Data.dll从4.0.0.0到5.0.414.0后,DropDownList绑定数据时抛出异常:
System.InvalidOperationException: Data source is an invalid type. It must be either an IListSource, IEnumerable, or IDataSource.
出错代码片段
this.CategoryDropDownList.DataTextField = "CAT_NAME"; this.CategoryDropDownList.DataValueField = "CAT_ID"; this.CategoryDropDownList.DataSource = mgr.GetCategories();// 此处报错 this.CategoryDropDownList.DataBind();
原GetCategories实现
public IDataReader GetCategories() { IDataReader reader = null; using (var cmd = MyDB.GetSqlStringCommand(MySqlScriptor.GetSql("QueryCategories"))) { reader = MyDB.ExecuteReader(cmd); } return reader; }
问题根源:5.0版本中ExecuteReader返回的RefCountingDataReader不再实现IEnumerable接口(4.0版本的实现支持该接口),导致DropDownList无法识别该数据源类型。强制转换为IDataSource也无效,因为RefCountingDataReader并未实现此接口。
可行解决方案
方案1:将DataReader数据转换为可枚举集合
把IDataReader中的数据读取到List<T>或DataTable这类符合要求的容器中,再进行绑定。
方式1:使用实体类集合
// 定义Category实体类 public class Category { public int CAT_ID { get; set; } public string CAT_NAME { get; set; } } // 修改后的GetCategories方法 public List<Category> GetCategories() { var categories = new List<Category>(); using (var cmd = MyDB.GetSqlStringCommand(MySqlScriptor.GetSql("QueryCategories"))) { using (var reader = MyDB.ExecuteReader(cmd)) { while (reader.Read()) { categories.Add(new Category { CAT_ID = reader.GetInt32(reader.GetOrdinal("CAT_ID")), CAT_NAME = reader.GetString(reader.GetOrdinal("CAT_NAME")) }); } } } return categories; }
方式2:使用DataTable(无需定义实体)
public DataTable GetCategories() { DataTable dt = new DataTable(); using (var cmd = MyDB.GetSqlStringCommand(MySqlScriptor.GetSql("QueryCategories"))) { using (var reader = MyDB.ExecuteReader(cmd)) { dt.Load(reader); } } return dt; }
方案2:改用ExecuteDataSet方法
直接使用Enterprise Library的ExecuteDataSet获取数据集,返回其中的DataTable作为数据源:
public DataTable GetCategories() { using (var cmd = MyDB.GetSqlStringCommand(MySqlScriptor.GetSql("QueryCategories"))) { var ds = MyDB.ExecuteDataSet(cmd); return ds.Tables[0]; } }
说明
两种方案都能让数据源满足DropDownList的类型要求(List<T>和DataTable均实现IEnumerable或IListSource接口),绑定代码无需修改即可正常运行。
内容的提问来源于stack exchange,提问作者delma wax
相关产品推荐
相关产品推荐

