msdn中给出的例子都是通过datatable来给表值参数传值,但是提到一句“System.Data.SqlClient 支持从 DataTable、DbDataReader 或 IList 对象填充表值参数。”
我用ILIst传参,就报错了,提示“InvalidCastException: 将参数值从IList`1 转换到 IEnumerable`1 失败。]”,这是咋回事,有谁知道吗,网上有人贴了一个使用IList的例子,结果也报同样的错误(鄙视这种不负责任的做法),有人成功实现过吗?谢谢

解决方案 »

  1.   

    1.虽然MsSql引入表值参数给数据库开发带来很大的方便,
    但是考虑到通信层面的通用性,还是传递串行数据更合适
    2.就楼主的问题,代码大致是这样:
    //声明表值参数
    SqlParameter _param = new SqlParameter("@参数名称", SqlDbType.Structured);
    //传值
    _param.Value = 获取一个IList类型的对象();
    //设置表值参数的类型名称
    _param.TypeName = "dbo.数据库中自定义的表值类型的名称";
      

  2.   

    我就是这么写的,结果报错。
    [InvalidCastException: 对象必须实现 IConvertible。]
       System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) +9508965
       System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType) +5075522[InvalidCastException: 将参数值从 List`1 转换到 IEnumerable`1 失败。]
       System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType) +5074733
       System.Data.SqlClient.SqlParameter.GetCoercedValue() +32
       System.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc) +103
       System.Data.SqlClient.SqlCommand.SetUpRPCParameters(_SqlRPC rpc, Int32 startCount, Boolean inSchema, SqlParameterCollection parameters) +126
       System.Data.SqlClient.SqlCommand.BuildRPC(Boolean inSchema, SqlParameterCollection parameters, _SqlRPC& rpc) +73
       System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +987
       System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162
       System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) +178
       System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +137
      

  3.   

    @microtry
                tStockInBill entity = null;
                List<tStockInBillDetail> listDetail = null;
                StockBusiness.GetStockInBillBysibNo(sibNo, out entity, out listDetail);
                List<SqlParameter> listParams = new List<SqlParameter>()
                {
                    SqlHelper.CreateSqlParameter("@sibNo",sibNo),
                    SqlHelper.CreateSqlParameter("@dciNo",entity.dciNo)
                };
                //寻求使用IList传参的方式
                SqlParameter parm = new SqlParameter("@siDetail", listDetail);
                parm.SqlDbType = SqlDbType.Structured;
                parm.TypeName = "dbo.tStockInBillDetailType";
                listParams.Add(parm);就是EntityFramework中定义的对象
      

  4.   

    这个问题昨天我也碰到了,今天和老大合力终于搞出了点眉目,希望对你有所帮助public static IList<cComp_MarkInfoObj> P_Comp_QueryMarkByIds(IList<IDsObj> list)
            {
                if (list.Count > 0)
                {
                    SqlParameter[] para = new SqlParameter[]{new SqlParameter()};
                    IEnumerable<IDsObj> li = list.OfType<IDsObj>();
                    #region datatable模式
                    //DataTable dt = new DataTable();
                    //dt.Columns.Add("ID", Type.GetType("System.Int32"));
                    //dt.Columns.Add("MarkID", Type.GetType("System.Int32"));
                    //dt.Columns.Add("ProductID", Type.GetType("System.Int32"));
                    //dt.Columns.Add("CompID", Type.GetType("System.Int32"));
                    //dt.Columns.Add("UserID", Type.GetType("System.Int32"));
                    //foreach(IDsObj obj in list)
                    //{
                    //    DataRow dr = dt.NewRow();
                    //    dr[0] = obj.ID;
                    //    dr[1] = obj.MarkID;
                    //    dr[2] = obj.MarkID;
                    //    dr[3] = obj.MarkID;
                    //    dr[4] = obj.MarkID;
                    //    dt.Rows.Add(dr);
                    //}
                    #endregion
                    IList<SqlDataRecord> listNew = new List<SqlDataRecord>();
                    SqlMetaData[] MetaData = new SqlMetaData[] { 
                        new SqlMetaData("ID", SqlDbType.Int),
                        new SqlMetaData("MarkID", SqlDbType.Int),
                        new SqlMetaData("ProductID", SqlDbType.Int),
                        new SqlMetaData("CompID", SqlDbType.Int),
                        new SqlMetaData("UserID", SqlDbType.Int) };
                    foreach (IDsObj obj in list)
                    {
                        var a = new SqlDataRecord(MetaData);
                        a.SetInt32(0, obj.ID);
                        a.SetInt32(1, obj.MarkID);
                        a.SetInt32(2, obj.MarkID);
                        a.SetInt32(3, obj.MarkID);
                        a.SetInt32(4, obj.MarkID);
                        listNew.Add(a);
                    }                para[0].Value = listNew;
                    para[0].TypeName = "dbo.ID_Table";
                    para[0].SqlDbType = SqlDbType.Structured;
                    para[0].ParameterName = "@Tab";
                    return DbPublic.GetPageList<cComp_MarkInfoObj>(ICon.CnnString, "P_Comp_QueryMarkByIds", CommandType.StoredProcedure, para);
                }
                return null;
            }