Я не уверен, что это возможно, но я просто не мог понять. У меня есть SP в моей БД, как показано ниже:
CREATE PROCEDURE [dbo].[GetMyValue]
AS
SELECT Code, TypeDesc FROM IDType
SELECT Code, Race FROM Race
SELECT Code, Nation FROM Nationality
SELECT Code, [Language name] AS 'Language' FROM Languages
SELECT Code, Occupation FROM Occupation
SELECT Code, Country FROM Country
GO
То, что я пытаюсь сделать, - сопоставить таблицу с именем таблицы из БД следующим образом:
Dim da As New SqlDataAdapter(cmd)
da.TableMappings.Add("IDType", "NRICType")
da.TableMappings.Add("Race", "Race")
da.TableMappings.Add("Nationality", "Nationality")
da.TableMappings.Add("Languages", "Languages")
da.TableMappings.Add("Occupation", "Occupation")
da.TableMappings.Add("Country", "Country")
da.Fill(ds)
вместо использования TableN:
Dim da As New SqlDataAdapter(cmd)
da.TableMappings.Add("Table", "NRICType")
da.TableMappings.Add("Table1", "Race")
da.TableMappings.Add("Table2", "Nationality")
da.TableMappings.Add("Table3", "Languages")
da.TableMappings.Add("Table4", "Occupation")
da.TableMappings.Add("Table5", "Country")
da.Fill(ds)
Во всяком случае, это не работает, когда я пытаюсь получить доступ к значению в последней части с помощью Dim dt As DataTable = ds.Tables("NRICType")
. ds.Tables("NRICType")
выглядят как NULL
. Все работает нормально, когда я сопоставляю его с TableN.
Но в будущем может возникнуть проблема: что если последовательность SELECT STATEMENT
в SP изменилась? Отображение определенно испортится. Код в С# тоже поможет.
Chinz,
Вот хак, который даст вам то, что вы ищете...
В вашей Хранимой процедуре добавьте еще одно поле (TableName) к вашим выборам
CREATE PROCEDURE [dbo].[GetMyValue]
AS
SELECT 'IDType' TableName, Code, TypeDesc FROM IDType
SELECT 'Race' TableName, Code, Race FROM Race
SELECT 'Nationality' TableName, Code, Nation FROM Nationality
SELECT 'Languages' TableName, Code, [Language name] AS 'Language' FROM Languages
SELECT 'Occupation' TableName, Code, Occupation FROM Occupation
SELECT 'Country' TableName, Code, Country FROM Country
GO
Теперь в вашем коде С# после da.Fill(ds)
da.Fill(ds);
for (int i = 0; i < ds.Tables.Count; i++)
{
if (i == 0)
da.TableMappings.Add("table", GetTableName(i, ds));
else
da.TableMappings.Add("table" + i.ToString(), GetTableName(i, ds));
}
GetTableName - это метод захвата первого поля из DataTable
static string GetTableName(int tableIndex, DataSet ds)
{
if (ds.Tables[tableIndex].Rows.Count > 0)
return ds.Tables[tableIndex].Rows[0]["TableName"].ToString();
// If there aren't any rows I don't know the Table name and return table[index] as the name
return "table" + tableIndex.ToString();
}
Другой способ сделать это - сделать первый выбор в хранимой процедуре порядком и названием таблиц. Затем в коде С# после da.Fill(ds) вы можете читать строки из ds.tables [0] и использовать их для сопоставлений таблиц.
Надеюсь, это поможет.
Если вы не хотите иметь дело с дополнительными нежелательными столбцами в своих результатах, тогда рассмотрите следующие
В вашей сохраненной процедуре будет выбран дополнительный выбор, который будет первым выбором и определит порядок возвращаемых таблиц.
CREATE PROCEDURE [dbo].[GetMyValue]
AS
SELECT 'IDType' TableName, 1 as SortOrder
UNION
SELECT 'Race' TableName , 2 as SortOrder
UNION
SELECT 'Nationality' TableName , 3 as SortOrder
UNION
SELECT 'Languages' TableName ,4 as SortOrder
UNION
SELECT 'Occupation' TableName , 5 as SortOrder
UNION
SELECT 'Country' TableName, 6 as SortOrder
ORDER BY SortOrder
SELECT Code, TypeDesc FROM IDType
SELECT Code, Race FROM Race
SELECT Code, Nation FROM Nationality
SELECT Code, [Language name] AS 'Language' FROM Languages
SELECT Code, Occupation FROM Occupation
SELECT Code, Country FROM Country
GO
и в коде С# после da.Fill(ds) сделать это
//string[] listOfTableNames;
listOfTableNames = GetTableNames(ds);
for (int i = 0; i < ds.Tables.Count; i++)
{
da.TableMappings.Add("table" + i.ToString(), listOfTableNames[i]);
}
и метод GetTableNames определяется как
static string[] GetTableNames( DataSet ds)
{
List<string> tablenames = new List<string>();
// The first Table contains the TABLE NAMES
tablenames.Add("TableNames");
if (ds.Tables[0].Rows.Count > 0)
foreach( DataRow row in ds.Tables[0].Rows)
{
tablenames.Add(row["TableName"].ToString());
}
return tablenames.ToArray();
}
Как описано в документации в MSDN, как это предполагается использовать.
http://msdn.microsoft.com/en-us/library/ms810286.aspx
Если хранимая процедура настроена в этом порядке, этот порядок должен поддерживаться в будущем.
Если вы хотите сделать этот Dynimac, вы можете проверить схему таблицы и попытаться определить, смотрите ли вы правильную таблицу, но это добавит большой стоимости в производительности.
Dim da As New SqlDataAdapter(cmd)
da.TableMappings.Add("Table", "NRICType")
da.TableMappings.Add("Table1", "Race")
da.TableMappings.Add("Table2", "Nationality")
da.TableMappings.Add("Table3", "Languages")
da.TableMappings.Add("Table4", "Occupation")
da.TableMappings.Add("Table5", "Country")
da.Fill(ds)
Второй пример - правильное использование этой функции.