日期:2014-05-17  浏览次数:20775 次

SqlDataAdapter.FillSchema方法执行存储过程返回的DataSet,有问题!
小弟,有几个存储过程,返回的数据集是一个DataSet包含两个DataTable,
其中存储过程里面都用到了临时表。

因为业务的需要,我必须得到第一个DataTable的表结构(就是存储过程中临时表的表结构),
如字段的类型、是否可空、最主要的是要获取字段的MaxLength属性。

然后我的数据访问代码如下:

            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                DataSet ds = new DataSet();
                try
                {
                    connection.Open();
                    SqlDataAdapter command = new SqlDataAdapter(SQLString, connection);
                    command.FillSchema(ds, SchemaType.Source);
                }
                catch (System.Data.SqlClient.SqlException ex)
                {
                    throw new Exception(ex.Message);
                }
                return ds;
            }

执行了出现异常,提示存储过程中的“#Temp”(临时表的名称)无效。 
我用SQL Server Profiler跟踪得到的执行语句是:

 SET FMTONLY OFF ;
 SET NO_BROWSETABLE ON ;
 SET FMTONLY ON ;
 EXEC SearchOrder @start = N'0', @limit = N'100', @OrderNo = NULL,
    @Mobele = NULL, @CustomerName = NULL, @OrderBeginDate = N'2011-08-01',
    @OrderEndDate = N'2011-08-09', @OrderTypeID = NULL, @OrderStatusID = NULL,
    @DrBusStationCode = NULL
 SET FMTONLY OFF ;
 SET NO_BROWSETABLE OFF ;

我存储过程写法绝对没有问题,因为我单独执行“EXEC SearchOrder  @start = N'0', @limit = N'100',......”是可以正常返回数据的。

现在请高手支招,这是神马情况?
或者我怎么才能得到存储过程中临时表的表结构。

------解决方案--------------------
一般的存储过程只在.dbml文件的设计视图中拖入即可,系统自动会形成方法。

Linq的存储过程返回的结果集如果不是实际存在的表(比如:临时表),没法生成模型类,就没法返回结果集了,这类存储过程生成的方法的结果集一般都是int类型。

有时候我们需要在存储过程里面写临时表,且将关联的若干张表的数据更新到临时表中来取数据,

而不使用视图或者左联右联,这样会提高查询的效率。

 

解决方法:


1、在数据库里创建一张表,结构要和临时表的列一致,比如叫T1;

2、把存储过程内容注释掉,改成简单的select * from T1;
3、把存储过程拖入设计器,编译。

4、修改存储过程为原来的代码,删掉T1表