如果您迫切需要这样做,我认为您不会使用纯强类型设计器生成的解决方案取得成功; tableadapter 旨在在 db 数据(您的强类型数据表)的本地数据表表示和返回行的数据库查询之间进行调解。 tableadapter 中的“表”与数据表相关,而不是数据库表。
单个 tableadapter 不打算充当 3 个本地数据表和提供 3 个数据库查询输出的远程过程之间的中介。主要是它不能这样做,因为客户端代码没有任何东西可以用来识别,对于你的 sql ......
Select ColA, ColB, ColC from TableA
Select ColD, ColE, ColF from TableB
Select ColG, ColH, ColI from TableC
...select * from TableA 的结果应该进入数据集中的 TableADataTable 等。数据来自 tableA 的事实在通过线路传输时丢失了,因为它完全不相关,甚至可能不是真的。
当 tableadapter 与单个 select 一起正确使用时,它会隐式知道结果应该放入的数据表。TableADataTable 具有相应的 TableATableAdapter,TableATableAdapter 从数据库中的某个位置选择数据并将其存储在 TableADataTable 中 - 有数据集中没有其他表被 TableATableAdapter 设计用于操作,因此它在运行查询后不需要任何关于数据块去向的提示。 TableATableAdapter 甚至可以加载一个根本不从数据库 TableA 返回任何数据的查询;只要它运行的查询产生一组正确的数字和类型的列,该数据就会进入 TableADataTable,因为这是 TableATableAdapter 硬编码要做的。它不服务于其他数据表,并且对任何其他数据表不感兴趣。
因为您的存储过程无法向 tableadapter 指示哪些结果集应该存储在哪个表中,所以您设想的解决方案无法工作。
简单的规则是:“一只狗,一个完成” - “一个db查询结果集,一个tableadapter,一个强类型数据表”
因此,我强烈建议您按预期使用这些东西:
- 为TableA、TableB和TableC创建3个tableadapter和对应的数据表
- 在您的代码中分别填写:
var ds = new StronglyTypedDataSet();
var ata as new TableATableAdapter();
ata.Fill(ds);
var bta as new TableBTableAdapter();
bta.Fill(ds);
var cta as new TableCTableAdapter();
cta.Fill(ds);
“我们希望避免对单个页面进行多次 db 调用”并没有真正的意义——这听起来像是您想象中的问题的解决方案,而不是真正会发生的问题。尝试一次执行这些操作而不是 3 次执行这些操作几乎没有性能优势。您可能不同意,但请测试一下 - 不要只是凭直觉。连接被池化,语句被缓存和准备,如果你真的认为它会有很大帮助的话,可以同时执行 3 个语句。
归根结底,如果您有 9 兆字节的数据要从数据库中提取,那么每次提取 3 mb 的数据与提取 9 的数据的 1 次之间的差异将是微乎其微的;您没有等待 30 秒打开连接,每秒读取 3 mb,等待另外 30 秒关闭它,广告必须重新完成(总时间 183 秒)并且所有瓶颈都归因于连接管理.即使您确实有一个超级延迟连接,需要 30 秒来传输 SELECT 并需要另外 30 秒来开始读取数据,您也可以同时启动 3 个请求,并且根据定义它需要相同的时间来发送3 个 SELECT 将调用 1 个过程调用(都需要 61 秒)
如果您不同意尝试将所有操作合二为一的原因是虚假的,那么您可能希望继续尝试通过您选择的方法进行操作,在这种情况下,我认为您将不得不选择:
使用标准的数据适配器和数据集
然后将数据移动到类型集以使用它
SqlConnection con = new SqlConnection("YourConnection String");
SqlDataAdapter da = new SqlDataAdapter();
DataSet ds = new DataSet();
SqlCommand cmd = new SqlCommand("storedprocedure", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@p1", whatever); //if you have parameters.
SqlDataAdapter da= new SqlDataAdapter(cmd);
da.Fill(ds);
con.Close();
现在您有一个包含 3 个表的数据集,您的问题是找出哪个表是哪个表。假设 ds.Tables[0] 用于 TableA:
foreach(var ro in ds.Tables[0].Rows)
typedDs.TableA.AddTableARow(ro.ItemArray);
对 b 和 c 表重复此操作
将您的 3 个查询转换为 1 个
您的示例似乎表明您的所有 3 个表都具有相同的列数。如果列也是相同的类型,那么您可以合并查询,并将它们加载到单个表适配器中并将它们填充到单个强类型数据表中。然后,您可能需要做更多的工作来将它们拆分为单独的数据表。也许修改查询以返回一列,以便您可以跟踪数据的来源:
Select 'tableA' as wherefrom, ColA, ColB, ColC from TableA
UNION ALL
Select 'tableB' as wherefrom, ColD, ColE, ColF from TableB
UNION ALL
Select 'tableC' as wherefrom, ColG, ColH, ColI from TableC
这是一团糟,一个麻烦,一个黑客
为什么这么难?好吧.. 引用另一句老话:如果很难,那你就做错了。 TableAdapters 是以 X 方式设计的,而您正试图以 Y 方式使用它们。退后一步,检查你这样做的原因——这才是真正的问题所在