Как заполнить общий список объектов в C# из базы данных SQL

Я только учусь ASP.NET c# и пытается включить лучшие практики в Мои приложения. Все, что я читаю, говорит о слое моих приложений в DAL, BLL, UI и т. д. На основе разделения проблем. Вместо того, чтобы передавать datatables, я думаю об использовании пользовательских объектов, чтобы я был слабо связан с моим уровнем данных и мог воспользоваться intellisense в VS. Я предполагаю, что эти объекты будут считаться DTOs?

во-первых, где эти объекты находятся в моей слои? БЛЛ, дал, другие?

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

в-третьих, все, что я вижу в эти дни говорит использовать Linq2SQL. Я планирую изучить Linq2SQL, но в на этот раз я работаю с устаревшей базой данных, у которой нет внешних ключей, и у меня нет возможности исправить ее atm. Кроме того, я хочу узнать больше о c#, прежде чем я начну получать решения ORM, такие как nHibernate. В то же время я не хочу печатать все соединения и SQL-сантехнику для каждого запроса. Можно ли сейчас использовать Enterprise DAAB?

2 ответов


у вас много вопросов в одном вопросе.

Linq2SQL-это просто вид ORM, если вы собираетесь по этому маршруту, я бы посмотрел на Entity framework (orm microsoft).

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

  • пользовательский интерфейс
  • BLL
  • даль

так что ваше общение-это переговоры UI в bll и переговоры БЛЛ в даль. DAL возвращает некоторые данные в BLL, который в свою очередь представляет его обратно в пользовательский интерфейс. Я не знаю, кто сказал вам, что наборы данных / таблицы плохие...конечно, читатель быстрее, но это не означает, что использование datatable плохо.

позвольте мне привести вам пример. Перестаньте думать о своем дале как об одном простом классе. Начните думать о слое DAL как о целом папка разных классов. Одним из этих классов является статический класс DB. Это статично, потому что вы имеете дело с одной базой данных (в большинстве случаев), поэтому нет необходимости создавать экземпляр класса. Так это может выглядеть так:

public static class DB {
private static readonly string connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
private static readonly DbProviderFactory factory = DbProviderFactories.GetFactory(dataProvider);

public static int Update(string sql)
        {
            using (DbConnection connection = factory.CreateConnection())
            {
                connection.ConnectionString = connectionString;

                using (DbCommand command = factory.CreateCommand())
                {
                    command.Connection = connection;
                    command.CommandText = sql;

                    connection.Open();
                    return command.ExecuteNonQuery();
                }
            }
        }

public static DataTable GetDataTable(string sql)
        {
            using (DbConnection connection = factory.CreateConnection())
            {
                connection.ConnectionString = connectionString;

                using (DbCommand command = factory.CreateCommand())
                {
                    command.Connection = connection;
                    command.CommandType = CommandType.Text;
                    command.CommandText = sql;

                    using (DbDataAdapter adapter = factory.CreateDataAdapter())
                    {
                        adapter.SelectCommand = command;

                        DataTable dt = new DataTable();
                        adapter.Fill(dt);

                        return dt;
                    }
                }
            }
}

некоторые из это было взято с сайта dofactory. Отличный ресурс, чтобы узнать, как использовать шаблоны проектирования. Во всяком случае, это только один .файл класса. Теперь вам нужен еще один, скажем, CustomerDAO (объект доступа к данным клиента).

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

public IList<Customer> GetCustomers()
{
    StringBuilder sql = new StringBuilder();
    sql.Append(" SELECT CustomerId, CompanyName, City, Country ");
    sql.Append("   FROM Customer ");

    DataTable dt = Db.GetDataTable(sql.ToString());

    return MakeCustomers(dt);
}

помните, что это совершенно разные .файл класса. Хорошо, так как клиенты выглядят:

private IList<Customer> MakeCustomers(DataTable dt)
        {
            IList<Customer> list = new List<Customer>();
            foreach (DataRow row in dt.Rows)
                list.Add(MakeCustomer(row));

            return list;
        }

Итак, что я делаю здесь, у меня был datatable полный клиентов. Мне нужно перебрать каждую строку datatable и сделать заказчик:

private Customer MakeCustomer(DataRow row)
        {
            int customerId = int.Parse(row["CustomerId"].ToString());
            string company = row["CompanyName"].ToString();
            string city = row["City"].ToString();
            string country = row["Country"].ToString();

            return new Customer(customerId, company, city, country);
        }

таким образом, этот клиент является новым и хранится в списке клиентов.

это всего лишь небольшой пример того, что делает ваш уровень доступа к данным. Класс database просто хранит строку подключения и функции для получения набора данных или таблицы данных или даже в вашем случае для чтения данных (что Вы тоже можете сделать). Класс CustomerDAO-это просто класс, который имеет дело с объектами клиента и может реализовать интерфейс ICustomer.

так где сам класс клиентов? Он может быть в другой папке в качестве бизнес-слоя, потому что это просто бизнес-объект. Здесь можно задать проверки и обязательные поля внутри класса customer.

ваш пользовательский интерфейс не имеет ничего, связанного с datareaders, datasets или SQL вообще. Ваш бизнес-уровень также не имеет к нему никакого отношения (он определяет некоторые правила для ваших бизнес-объектов). Ваш dal может быть очень гибким (может работать с SQL, Oracle и т. д.) Или может быть ограничен SQL Сервер, если это то, что вы планируете делать. Не перегружайте приложение. Если вы парень MS и уверены, что используете только SQL Server, не усложняйте свою работу, пытаясь развернуть окончательный DAL, который работает с любым поставщиком. можно использовать SQLCommand, SQLConnection и т. д.


перейти проверить OpenAccess ORM Telerik. Вам не нужно использовать его как "ORM", но он даст вам возможность быстро генерировать классы для ваших таблиц без необходимости вводить все это. Затем вы можете использовать эти строго типизированные классы в своем DAL для всего, что вы хотите, будь то пользовательский или ORM-based с чем-то другим. В этом случае вы просто используете его для генерации кода, чтобы быстро начать работу (и эти объекты очень просты и просты-т. е. именно там, где вы начнете если бы вы написали их от руки).

Что касается абстрагирования объектов DAL от других объектов, перейдите к WCF. Вы можете поместить его между каждым слоем (UI/Biz / DAL), и он будет генерировать прокси-объекты, которые позаботятся о вашем разделении проблем.