TableMappings с TableName вместо TableN

1

Я не уверен, что это возможно, но я просто не мог понять. У меня есть 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 изменилась? Отображение определенно испортится. Код в С# тоже поможет.

Теги:
sql-server

2 ответа

2
Лучший ответ

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();
}
  • 0
    ,Спасибо. но с этим у меня будет целая группа повторяющихся значений в TableName, которая будет выбрана. Неплохая альтернатива через, будет использовать это в качестве последнего ресурса. +1.
  • 0
    @chinz, я обновил свой ответ, чтобы отразить твои опасения.
0

Как описано в документации в 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)

Второй пример - правильное использование этой функции.

  • 0
    Благодарю. Я прошел через ту же статью раньше. во всяком случае, это было 12 лет назад, я сомневаюсь, что это применяется до сих пор.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню