C # Database Mapper - PullRequest
       24

C # Database Mapper

1 голос
/ 22 октября 2011

Я искал, чтобы сопоставить результаты моего запроса к базе данных со строгим типом объектов в моем коде c #.Поэтому я написал быстрый и грязный вспомогательный метод для класса SqlConnection, который выполняет запрос к базе данных и использует отражение для сопоставления столбцов записи со свойствами объекта.Код ниже:

 public static T Query<T>(this SqlConnection conn, string query) where T : new()
    {
        T obj = default(T);

        using (SqlCommand command = new SqlCommand(query, conn))
        {
            using (SqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    obj = new T();

                    PropertyInfo[] propertyInfos;
                    propertyInfos = typeof(T).GetProperties();

                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        var name = reader.GetName(i);

                        foreach (var item in propertyInfos)
                        {
                            if (item.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase) && item.CanWrite)
                            {
                                item.SetValue(obj, reader[i], null);
                            }
                        }

                    }
                }
            }
        }

        return obj;
    }

  public class User
    {
        public int id { get; set; }
        public string firstname { get; set; }
        public string lastname { get; set; }
        public DateTime signupDate { get; set; }
        public int age { get; set; }
        public string gender { get; set; }
    }


   var user = conn.Query<User>("select id,firstname,lastname from users");      

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

Я думаю, что, возможно, я смогу улучшить код в вспомогательном методе, удалив цикл для propertyInfos и используя вместо него словарь.Есть ли что-то еще, что нужно настроить?

PS: я знаю о Dapper, я просто хотел реализовать нечто подобное самостоятельно, чтобы помочь мне учиться лучше.

Ответы [ 2 ]

2 голосов
/ 22 октября 2011

То, что вы сделали, в основном то, что linq-to-sql или другие OR-мапперы делают под капотом. Чтобы узнать подробности о том, как это работает, всегда полезно написать что-то с нуля.

Если вы хотите больше вдохновения или хотите иметь что-то готовое для промышленного использования, я бы порекомендовал почитать на linq-to-sql. Это легкий, но компетентный.

0 голосов
/ 22 октября 2011

Есть несколько вещей, о которых я могу подумать:

  1. Я думаю, что для пропуска цикла вы можете использовать:

    reader[item.Name]
    
  2. Я сам делал что-то подобное, но я никогда не сталкивался с брезгливостью.Я не уверен, использует ли он рефлексию, но всегда полезно почитать чужой код, чтобы отточить свое мастерство (Скотт Хансельман часто рекомендует это делать).

  3. Вы также можете посмотретьat: http://www.codeproject.com/KB/database/metaquery_part1.aspx

  4. Вы можете реализовать атрибут, который отображает поле в столбец базы данных, но это просто для удовольствия.

Редактировать:

5: Вы также можете пропустить цикл while для считывателя и просто взять первую строку и задокументировать тот факт, что ваш запрос возвращает только один объект, поэтому он не вытягивает тысячу строк, если запрос возвращает тысячустроки.

...