#c# #orm #dapper
#c# #orm #dapper
Вопрос:
Я хотел сопоставить результаты запроса к базе данных с объектами строгого типа в моем коде 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) amp;amp; 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 и используя вместо него словарь. Есть ли что-нибудь еще, что нужно настроить?
P.S: я знаю о Dapper, я просто хотел реализовать что-то подобное самостоятельно, чтобы помочь мне лучше учиться.
Ответ №1:
То, что вы сделали, — это в основном то, что linq-to-sql или другие OR-mappers делают под капотом. Чтобы узнать подробности о том, как это работает, всегда полезно написать что-то с нуля.
Если вы хотите больше вдохновения или хотите иметь что-то готовое для использования в производстве «из коробки», я бы рекомендовал ознакомиться с linq-to-sql. Он легкий, но компетентный.
Комментарии:
1. Спасибо, Андерс, я уже некоторое время использую linq-to-sql, но я хотел, чтобы что-то просто работало с POCOs, и я хотел, чтобы производительность была как можно ближе к родной ADO.NET . Мне также надоело изучать новые реализации, которые Microsoft предлагает нам, LINQ2SQL, Entity… только для того, чтобы спустя несколько месяцев обнаружить, что они переходят к чему-то новому, потому что их последнее предложение работает не так хорошо.
Ответ №2:
Есть несколько вещей, о которых я могу думать:
- Я думаю, что для того, чтобы пропустить цикл, вы можете использовать:
reader[item.Name]
- Я сам делал что-то подобное, но я никогда не сталкивался с dapper. Я не уверен, использует ли он отражение, но всегда полезно прочитать чужой код, чтобы отточить свои навыки (Скотт Хансельман часто рекомендует это делать).
- Вы также можете посмотреть: http://www.codeproject.com/KB/database/metaquery_part1.aspx
- Вы можете реализовать атрибут, который сопоставляет поле со столбцом базы данных, но это просто для развлечения.
Редактировать:
5. Вы также можете пропустить цикл while над программой чтения и просто взять первую строку и задокументировать тот факт, что ваш запрос возвращает только один объект, поэтому он не извлекает тысячу строк, если запрос возвращает тысячу строк.
Комментарии:
1. Dapper не использует отражение, а скорее компилирует код для гораздо более быстрого выполнения. Кстати: Dapper используется здесь в Stackoverflow. А для получения дополнительной информации ознакомьтесь с Dapper, PetaPoco и Massive; все три представляют собой библиотеки данных с одним файлом micro ORM .
2. да, я узнал в ходе своего тестирования, что SetValu — это реальная проблема с производительностью, когда я использовал секундомер для определения времени производительности, теперь я пытаюсь узнать об использовании IL для повышения производительности. Да, я знаю о dapper, sam saffron и о том, как он используется в производстве на SO itself. Я также немного читал о PetaPoco, мне это тоже нравится — это именно то, что мне самому было нужно. Я просто подумал, что вместо того, чтобы брать эти готовые к использованию библиотеки, почему бы просто не попробовать сделать это самостоятельно и узнать несколько вещей по пути, тем более, что все они сами по себе являются реализациями одного файла.