SqlDataReader и динамическое форматирование чтения данных

У меня есть приложение C#, которое читает данные из хранимой процедуры, а затем создает сообщение. Я использую SqlDataReader для чтения информации из базы данных. Раньше мне приходилось создавать новый класс каждый раз, когда у меня появляется сообщение другого типа, и оно выходит из-под контроля. Под разным я подразумеваю разное количество столбцов и / или разные типы данных, которые содержатся в каждом из столбцов. Я пытаюсь упростить добавление различных типов сообщений и не знаю, как динамически форматировать данные, когда я их читаю. Я попытался отформатировать данные после того, как они были прочитаны в мои переменные Data #, но это просто мусор, потому что они отформатированы как неправильный тип. Итак, единственный способ, которым я сейчас вижу, - обрабатывать данные, когда я читаю переменные, и я не могу понять, как.

Мой формат моего сообщения выглядит следующим образом:

Message
   Subject
   (Text)
     MessageHeader1
     MessageHeader2
     Title
     Header1
     Header2
     Header3
     (Data)
        Data1
        Data2
        Data3

Проблема в том, что переменные Data # могут содержать информацию разного типа. В настоящее время он может содержать строки, целые числа, даты, проценты и т. Д. Существует ли способ форматирования данных на основе другого значения или какого-либо другого метода, чтобы можно было правильно отформатировать данные другого типа?

if (dr.Read())
{
    message.Subject = dr["Subject"].ToString();
    message.MessageText = new AlertMessageText()
    {
        MessageHeader1 = dr["MessageHeader1"].ToString(),
        MessageHeader2 = dr["MessageHeader2"].ToString(),
        Title = dr["Title"].ToString(),
        Header1 = dr["Header1"].ToString(),
        Header2 = dr["Header2"].ToString(),
        Header3 = dr["Header3"].ToString(),
        MessageData = new List<AlertMessageData>(),
    };
}

...

while (dr.Read())
{
    message.MessageText.MessageData.Add(new AlertMessageData()
        {
            Data1 = string.Format("{0:n0}", dr["Data1"]),
            Data2 = string.Format("{0:n0}", dr["Data2"]),
            Data3 = string.Format("{0:MM/dd/yyyy}", dr["Data3"]),    // Formats Data as a Date 
        });
}

2 ответа

Решение

Чтобы определить тип данных значения и затем применить определенный формат, вы можете сделать это:

while (dr.Read())
{
    var msg = new AlertMessageData();
    for (int i = 1; i < 4; i++)
    {
         var value = dr["Data" + i];
         string format = "{0:n0}";
         if (value is DateTime)
         {
            format = "{0:MM/dd/yyyy}";
         } 
         else if (value is string)
         {
            format = "{0}";
         }      

         var stringValue = string.Format(format, value);
         if (i == 1) msg.Data1 = stringValue;
         if (i == 2) msg.Data2 = stringValue;
         if (i == 3) msg.Data3 = stringValue;
    }
    message.MessageText.MessageData.Add(msg);
}

Вы можете использовать IDataReader's GetFieldType() метод, чтобы найти тип поля.

Например, чтобы найти тип вашего первого поля, оно будет выглядеть так:

Type t = dr.GetFieldType(0)

Если вы знаете тип вашего поля, вы можете использовать один из методов "Get()" IDataReader для автоматического преобразования для вас. Например, если вы знали, что ваше первое поле было двойным, вы можете сделать это:

double d = dr.GetDouble(0);
Другие вопросы по тегам