首页 新闻 会员 周边

如何使用Enterprise Library5.0调用带表值参数(Table-valued parameter)的存储过程?没人这么用过???

0
悬赏园豆:80 [已解决问题] 解决于 2012-05-08 16:58

问题详细描述如下:我在SQL server中创建了带一个input,表值参数的存储过程,然后用Enterprise Library5.0调用这个存储过程,并将.net中DataTable类型的变量传进去。具体代码如下:
1.SQL:

View Code 创建存储过程
1         CREATE PROCEDURE [dbo].[CreatFoodTestTableType]
2 @foodTable FoodTableType readonly --表值参数类型FoodTableType已创建
3 AS
4 BEGIN
5 insert into PFood(CID,PageIndex) select CID,PageIndex from @foodTable
6 END

2.C#:

View Code
        public int Test()
{
//字符串从配置文件中读取
Database db1 = DatabaseFactory.CreateDatabase("ConnectionString");
DataTable dt = new DataTable();
DataColumn dc1 = new DataColumn("Id", typeof(int));
DataColumn dc2 = new DataColumn("PageIndex", typeof(int));
dt.Columns.AddRange(new DataColumn[] { dc1, dc2, dc3 });

for (int i = 0; i < 10; i++)
{
DataRow dr = dt.NewRow();
dr[0] = 10 + i;
dr[1] = 20 + i;
dt.Rows.Add(dr);
}
DbCommand cmd = db1.GetStoredProcCommand("CreatFoodTestTableType");

//这里的DbType不知道选什么
db1.AddInParameter(cmd, "@foodTable", DbType.Object, dt);
return db.ExecuteNonQuery(cmd);
}

存储过程我直接用ado.net测试可以成功(ado.net的SqlDataType中有个叫Udt类型),但enterprise Library5.0中没有那个类型,现在的问题就是如何使用Enterprise library调用带表值参数的存储过程,请各位大侠帮帮忙,小弟不胜感激

DT2的主页 DT2 | 初学一级 | 园豆:75
提问于:2012-04-04 17:15
< >
分享
最佳答案
0
        public static SqlCommand BatchSaveHotelSalesInfo(BatchSaveHotelSalesInfoParamEntity entity){    
            if(null == entity)
                throw new ArgumentNullException("entity");

            object value;
            
            SqlCommand sc = new SqlCommand("usp_BatchSaveHotelSalesInfo");
            sc.CommandType = CommandType.StoredProcedure;
            
            
                        
            //表类型参数不能为 DBNull, null 会自动转换成 Sql 语句里的 default
            value = entity.HotelSaleInfos.ToDataTable<THotelSalesInfoEntity>();
                        
            SqlParameter spHotelSaleInfos = new SqlParameter("@HotelSaleInfos", SqlDbType.Structured, -1 , ParameterDirection.Input , true, 0 , 0 , string.Empty, DataRowVersion.Default, value);
            sc.Parameters.Add(spHotelSaleInfos);
                        
            SqlParameter sp = new SqlParameter("@ReturnValue", SqlDbType.Int);
            sp.Direction = ParameterDirection.ReturnValue;
            sc.Parameters.Add(sp);
            return sc;
        }

 

        /// <summary>
        /// 将 List 转换为 DataTable, 只针对 T 中 的 public Property
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        public static DataTable ToDataTable<T>(this List<T> list) where T : class {
            if (list == null)
                return null;

            Type type = typeof(T);
            var ps = type.GetProperties();
            Type targetType;
            NullableConverter nullableConvert;
            List<DataColumn> cols = new List<DataColumn>();
            foreach(var p in ps){
                if(p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))){
                    nullableConvert = new NullableConverter(p.PropertyType);
                    targetType = nullableConvert.UnderlyingType;
                    cols.Add(new DataColumn(p.Name, targetType));
                }else{
                    cols.Add(new DataColumn(p.Name, p.PropertyType));
                }
            }
            //var cols = from p in ps
            //           let pp = p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)
            //           select new DataColumn(p.Name, p.PropertyType);

            DataTable dt = new DataTable();
            dt.Columns.AddRange(cols.ToArray());

            list.ForEach((l) => {
                List<object> objs = new List<object>();
                objs.AddRange(ps.Select(p => p.GetValue(l, null)));
                dt.Rows.Add(objs.ToArray());
            });

            return dt;
        }
收获园豆:55
xling | 初学一级 |园豆:6 | 2012-04-13 15:52
其他回答(2)
0

晕,这样也可以吗? 能不能贴上你的 ado.net的代码,让我学习一下

收获园豆:10
ChatinCode | 园豆:2272 (老鸟四级) | 2012-04-05 10:06
0

存储过程中定义的是什么就用什么。

如果用SqlCommand,可以不指定DbType,比如:

command.Parameters.AddWithValue("@Title",doc.Title);
收获园豆:15
dudu | 园豆:31003 (高人七级) | 2012-04-05 14:58

你说的方法我试过,就是把Database和DbCommand分别as为SqlDatabase和SqlCommand 

但执行ExecuteNonQuery方法返回值为-1而不是10,虽然数据确实已经被insert进数据库了

支持(0) 反对(0) DT2 | 园豆:75 (初学一级) | 2012-04-05 16:27

@DT2: 不要as, 直接用SqlDatabase和SqlCommand

支持(0) 反对(0) dudu | 园豆:31003 (高人七级) | 2012-04-05 16:53

@DT2: 能不能贴上你的 ado.net的代码,让我学习一下?

支持(0) 反对(0) ChatinCode | 园豆:2272 (老鸟四级) | 2012-04-06 09:16

@dudu: 

DatabaseFactory.CreateDatabase("ConnectionString");这个方法创建的Database就是一个通用的DB,如果不as怎么得到SqlDatabase?还有就是,如果直接用ado.net的访问方式就跟Enterprise library没关系了啊
支持(0) 反对(0) DT2 | 园豆:75 (初学一级) | 2012-04-09 10:20

@ChatinCode: 

View Code
 1 ado.net的访问方式如下:
2
3 string dbCon = "Data Source=.;Initial Catalog=Food;Integrated Security=True";
4 using (SqlConnection conn = new SqlConnection(dbCon))
5 {
6 SqlCommand cmd = new SqlCommand("CreatFoodTestTableType", conn);
7 cmd.CommandType = CommandType.StoredProcedure;
8 cmd.Parameters.AddWithValue("@foodTable", dt);
9 conn.Open();
10 int i = cmd.ExecuteNonQuery();
11 return i;
12 }
13
14 仅供参考,如有不对的地方,请指正,谢谢!
支持(0) 反对(0) DT2 | 园豆:75 (初学一级) | 2012-04-09 10:25

@DT2: 谢谢,FoodTableType 的定义呢? 代码方便贴出来吗?

支持(0) 反对(0) ChatinCode | 园豆:2272 (老鸟四级) | 2012-04-09 11:51
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册