Лучший способ преобразовать типизированные данные объекта в тип значения - PullRequest
1 голос
/ 09 ноября 2011

Мне было поручено создать код, который будет извлекать данные из базы данных с использованием устройства чтения данных, и мне любопытно, что будет наилучшей практикой между тремя методами, которые я мог бы использовать ниже для преобразования данных из моего устройства чтения данных, которое путемвыборка по умолчанию с типом объекта.

    internal static RoomType SelectRoomType(int roomTypeID)
    {
        SqlCommand commRoomTypeSelector = ConnectionManager.MainConnection.CreateCommand();
        commRoomTypeSelector.CommandType = CommandType.StoredProcedure;
        commRoomTypeSelector.CommandText = "Rooms.asp_RMS_RoomType_Select";
        commRoomTypeSelector.Parameters.AddWithValue("RoomTypeID", roomTypeID);

        SqlDataReader dreadRoomType = commRoomTypeSelector.ExecuteReader();
        if (dreadRoomType.FieldCount != 0)
        {
            dreadRoomType.Read();
            RoomType roomType = new RoomType();
            roomType.RoomTypeID = (int)dreadRoomType["RoomTypeID"];
            roomType.RoomTypeName = (string)dreadRoomType["RoomType"];
            roomType.IsActive = ((string)dreadRoomType["IsActive"]).ToUpper() == "Y";
            roomType.LastEditDate = (string)dreadRoomType["LastEditDate"] != string.Empty ? DateTime.Parse((string)dreadRoomType["LastEditDate"]) : DateTime.MinValue;
            roomType.LastEditUser = (string)dreadRoomType["LastEditUser"];
            dreadRoomType.Close();
            return roomType;
        }
        dreadRoomType.Close();
        return null;
    }

Что меня смущает, так это распаковка, согласно http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx Бокс и распаковка довольно дорогие и их следует избегать ,Я знаю, что мог бы использовать

   int.Parse(dreadRoomType["RoomTypeID"].ToString())

вместо

   roomType.RoomTypeID = (int)dreadRoomType["RoomTypeID"];

Вопрос в том, есть ли еще способы преобразования этих данных гораздо более эффективным способом, чем оба варианта и еслинет никаких возможных способов, какой из двух способов вы предпочитаете использовать.Заранее спасибо вся помощь и предложения принимаются:)

Ответы [ 5 ]

3 голосов
/ 09 ноября 2011

Бокс не , что дорого.

Другие альтернативы не помогут; когда у вас есть object, он уже в штучной упаковке.
В частности, разбор строк, вероятно, намного дороже, чем бокс. (хотя я не измерял)

Если существует типизированный API, вы можете использовать его, чтобы избежать бокса (например, вызвать GetInt32).
(хотя эти типизированные методы иногда являются просто обертками вокруг нетипизированного метода, так что они тоже упаковываются)


Итог: Не беспокойтесь об этом .

Это руководство говорит вам, во-первых, избегать упаковки вещей, используя, где это возможно, типизированные (общие) коллекции

3 голосов
/ 09 ноября 2011

Вы можете использовать SqlDataReader.GetInt32(), чтобы избежать необходимости повторного преобразования / синтаксического анализа в int, для этого вам нужно знать, по какому индексу целое число находится в выбранных столбцах:

roomType.RoomTypeID = dreadRoomType.GetInt32(0);
2 голосов
/ 09 ноября 2011

Если бокс / распаковка "медленный" (на самом деле это не так) ... почему бы преобразовать в строку и обратно не было бы слишком медленно?(Это действительно пустая трата: бокс / распаковка значительно быстрее.) Я бы сначала удостоверился, что есть проблема с производительностью , прежде чем беспокоиться об этом, однако ...

По своему опыту, для моих данных, которые включают тысячи загруженных элементов одновременно, я обнаружил, что можно значительно повысить производительность с предварительным определением индексов столбцов (носделайте это динамически с GetOrdinal!), а потом я не буду беспокоиться об остальном:)

Для одного элемента, как в этом посте, я бы даже не беспокоился об ординалах: это совершенно другоеВариант использования и «дорогая» часть говорит с базой данных.

Счастливое кодирование.

1 голос
/ 09 ноября 2011

Упаковка и распаковка не так дороги, как анализ строки и извлечение int. Пожалуйста, профилируйте, прежде чем делать преждевременную оптимизацию.

0 голосов
/ 30 июля 2013
    private static void GetValue<T>(object o, ref T defaultValue)
    {
        try
        {
            if (defaultValue == null)
            {
                throw new Exception("Default value cannot be null");
            }
            else if (o != null)
            {
                if ((o is T))
                {
                    defaultValue = (T)o;
                }
            }
        }
        catch (Exception)
        {
            throw;
        }
    }

Вы можете использовать указанный выше метод для преобразования объекта в любой базовый тип данных следующим образом.
Конвертировать в dateTime

    public static DateTime GetDateTime(object o, DateTime defaultValue)
    {
        try
        {
            GetValue<DateTime>(o, ref defaultValue);
            return defaultValue;
        }
        catch (Exception)
        {
            throw;
        }
    }

Преобразовать в целое число

    public static int GetInteger(object o, int defaultValue)
    {
        try
        {
            GetValue<int>(o, ref defaultValue);
            return defaultValue;
        }
        catch (Exception)
        {
            throw;
        }
    }

Ссылка и загрузка полного кода со всеми основными типами данных здесь http://www.dotnetlines.com/Blogs/tabid/85/EntryId/39/Convert-Object-type-into-its-specific-data-type-using-a-Generic-Method.aspx

...