Как получить доступ к неоднозначным столбцам в запросе SQL с помощью SELECT * - PullRequest
1 голос
/ 16 ноября 2010

Когда я выполняю хранимую процедуру

SELECT * FROM Users 
INNER JOIN BloodBankUser ON Users.UserID = BloodBankUser.UserID

Это дает мне хороший результат.

, но теперь на стороне .net

dt.Rows[0]["Address"].ToString();

это дает мне адрес таблицы BloodBankUser

dt.Rows[0]["Users.Address"].ToString();

Когда я отлаживаю этот оператор, он выполняет ошибку

Столбец «Users.Address» не принадлежит таблице.

Как узнать значение Users.Address

Ответы [ 5 ]

3 голосов
/ 16 ноября 2010

Хотя первым ответом было бы изменить ваш SQL-запрос, указав отдельное имя для каждого из ваших полей, все еще возможно получить имя таблицы, связанной с вашим полем.

В этом примере яя не заполняю DataTable с помощью DataAdapter, а скорее использую SqlDataReader.

Имейте в виду, что это может не сработать, если по какой-либо причине вы не можете получить схему базы данных

При вызове ExecuteReader на SqlCommand возникает перегрузка, позволяющая указать CommandBehavior.В нашем случае, поведение, которое мы хотим, это CommandBehavior.KeyInfo.

var reader = command.ExecuteReader(CommandBehavior.KeyInfo);

Теперь, на ридере, вы можете вызвать метод GetSchemaTable.Он возвращает DataTable, который содержит структуру вашего запроса.

var schema = reader.GetSchemaTable();

Вы можете прочитать об этой таблице в MSDN .

Теперь наша цель - соответствоватьполе и таблица против его порядкового положения в списке столбцов.Три поля из таблицы схемы соответствуют вашим интересам:

  • ColumnName
  • BaseTableName
  • ColumnOrdinal

Затем можно создатьметод расширения, чтобы сделать это чтение:

public static T Field<T>(this SqlDataReader reader, DataTable schema, string table, string field)
{
    // Search for the ordinal that match the table and field name
    var row = schema.AsEnumerable().FirstOrDefault(r => r.Field<string>("BaseTableName") == table && r.Field<string>("ColumnName") == field);
    var ordinal = row.Field<int>("ColumnOrdinal");

    return (T)reader.GetValue(ordinal);
}

Вы можете затем вызвать этот метод расширения

using (SqlConnection connection = new SqlConnection("your connection string"))
{
    connection.Open();

    using (SqlCommand command = new SqlCommand("SELECT * FROM Users INNER JOIN BloodBankUser ON Users.UserID = BloodBankUser.UserID;", connection))
    using (var reader = command.ExecuteReader(CommandBehavior.KeyInfo))
    {
        var schema = reader.GetSchemaTable();

        while (reader.Read())
        {
            Console.WriteLine(reader.Field<string>(schema, "Users", "Address"));
        }
    }
}
3 голосов
/ 16 ноября 2010

Переименование ПОЛЯ в выводе (выберите FIELDNAME как NEWNAME)

1 голос
/ 16 ноября 2010

Вы указываете имена столбцов, а не используете SELECT * FROM После этого вы сможете сделать следующее

Select User.Username,
       User.Address as 'UserAddress',
       BloodBankUser.Address as 'BloodbankAddress'

FROM Users 
INNER JOIN BloodBankUser ON Users.UserID = BloodBankUser.UserID 
0 голосов
/ 16 ноября 2010

Insead из SELECT *... указывает столбцы, которые вы хотите явно, и псевдоним те, которые могут дублировать

SELECT Users.Address as UsersAddress
0 голосов
/ 16 ноября 2010

Избегайте использования * в SELECT запросах. Выберите только нужные столбцы и назовите их явно, чтобы избежать двусмысленности,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...