Как мне преобразовать результаты SQL в список объектов в C #? - PullRequest
1 голос
/ 24 августа 2010

Я работаю над преобразованием веб-приложения в настольное приложение WPF. Я хочу использовать существующий слой доступа к данным, поэтому мне не нужно переписывать все запросы SQL.

Но, в сущности, все заполнено почти исключительно из DataTables, возвращаемых из SQL-запросов. Чтобы сделать вещи немного проще в управлении, в некоторых случаях было бы неплохо преобразовать эти вещи в объекты.

Например, у меня есть запрос, который извлекает информацию из отчета. Я могу получить 500 результатов с такими столбцами, как ReportID, ReportTitle, ReportDate.

Я хотел бы создать класс отчета, который имеет эти открытые атрибуты, и каким-то образом преобразовать результаты SQL-запроса в коллекцию этих объектов отчета.

Каков наилучший способ сделать это?

Супер бонусные баллы, если есть простой способ вернуться назад (обновление базы данных, если объекты изменены).

Ответы [ 4 ]

5 голосов
/ 24 августа 2010

Вы должны узнать о объектно-реляционном сопоставлении (ORM) . Хороший ORM может сэкономить вам массу работы в будущем и избавит вас от этих неприятных запросов из вашего кода.

Я бы рекомендовал NHibernate или Entity Framework 4.0

4 голосов
/ 24 августа 2010

Хотя я также хотел бы предложить ORM (NHibernate это путь :)), возможное решение:

public IEnumerable<Report> ToReportList(DataTable dt)
{
  return dt.AsEnumerable().Select(dr => new Report
                                        {
                                            member1 = dr["column1"].ToString(),
                                            ...
                                        });
}

Кстати, твой класс здесь. Так,

internal class Report
{
  public string member1{ get; set;}
  ...
}

Вы также можете проверить это,

Я думаю, что если вы будете искать в стеке поток, вы найдете более удачные примеры, поскольку я помню, как узнал об этом здесь.

Кстати, если вы используете NHibernate, вам вообще не придется переписывать свои запросы. Все, что вам нужно сделать, это сопоставить ваши столы с классом и еще раз. Он будет обрабатывать все ваши DML-вещи (в основном, в основном), и вы можете легко сказать ORM выполнить LazyLoad, пакетную обработку и т. Д., Что довольно здорово.

Супер бонусные баллы, если есть легкий путь назад (обновление база данных, если объекты изменены).

Для этого перейдите на ORM, то есть на NHibernate (я знаю, что я предвзятый :)). Для примеров LINQ to SQL проверьте 2 ссылки ниже:

1 голос
/ 24 августа 2010

+ 1 ОРМ. Entity Framework хорош, LINQ to SQL тоже хорош, но вам нужен хороший дизайн базы данных, и он лучше подходит для довольно простых действий SQL CRUD. Для пользовательских сущностей из нескольких источников данных я бы выбрал EF.

Что касается обратного обновления - LINQ to SQL имеет простую реализацию, вроде этого, - скажем, у вас есть база данных MyDatabase с сущностями Dog:

using(MyDatabaseDataContext db = new MyDatabaseDataContext())
{
    //LINQ will automatically pluralize your items (entity named Dog becomes Dogs)
    Dog d = db.Dogs.Where(x=>x.DogName.Equals(dogName));
    d.Owner = "Steve";
    db.SubmitChanges();
    //adding new items is easy too
    Dog newdog = new Dog();
    newDog.DogName = "Scruff";
    newDog.Owner = "Jim";
    db.Dogs.Add(newDog);
    db.SubmitChanges();
}
0 голосов
/ 24 августа 2010

Проверьте этот метод.Сначала вы можете создать класс, который наследует DataContext.И затем вы можете использовать методы DataContext, такие как ExecuteQuery <>, чтобы конвертировать ваши результаты в объекты.С помощью этого метода вы можете напрямую использовать ваши запросы, которые вы написали ранее.Кроме того, я считаю, что этот способ намного лучше, чем поддержка файла .dbml, из-за проблем, связанных с синхронизацией с реальной схемой базы данных.

Рассмотрим следующий пример.Сначала вам нужно определить класс для взаимодействия с вашей базой данных

public class DBManagerDataContext : DataContext
{
    private static string connectionString = ""; // Your connection string

    public static DBManagerDataContext CreateInstance()
    {
        return new DBManagerDataContext(connectionString);
    }

    protected DBManagerDataContext(string connectionString)
        : base(connectionString, new AttributeMappingSource())
    {

    }
}

Затем вы можете использовать этот контекст для выполнения запросов и преобразования их в объекты, как показано ниже:

public class Report
{
    public int ReportID;
    public string ReportTitle;
    public DateTime ReportDate;

    private static string query = "select ReportID, ReportTitle, ReportDate from dbo.Reports"; // Your query

    public static List<Report> GetReportList()
    {
        DBManagerDataContext context = DBManagerDataContext.CreateInstance();
        return context.ExecuteQuery<Report>(query).ToList();
    }
}

Выможет использовать метод "GetReportList ()", приведенный выше, например, так:

List<Report> reports = Report.GetReportList();

В случае обновлений, метод, предложенный "jdandison", является хорошим вариантом, за исключением использования контекста данных каквыше.В случае обновлений это будет "ExecuteCommand", хотя.Пожалуйста, изучите класс DataContext для получения дополнительной информации.

Редактировать: Обратите внимание, что имена столбцов запросов должны соответствовать определению в объекте

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