Чтение из SQL таблицы базы данных, хранить в перечень объектов


 IList<WebSite> wsl = new List<WebSite>();
 login1 l = new login1();

 string q = "select Id, DomainUrl, IsApproved, Date from website where UserId = @UserId";

 using (MySqlConnection con = new MySqlConnection(WebConfigurationManager.ConnectionStrings["MySqlConnectionString"].ToString()))
 {
      using (MySqlCommand cmd = new MySqlCommand(q, con))
      {
           cmd.Parameters.Add("@UserId", MySqlDbType.Int32).Value = userId;
           con.Open();

           var reader = cmd.ExecuteReader();
           while (reader.Read())
           {
                var ws = new WebSite();
                ws.Id = reader.GetInt32("Id");
                ws.DomainUrl = reader.GetString("DomainUrl");
                ws.IsApproved = reader.GetBoolean("IsApproved");
                ws.User.Id = reader.GetInt32("UserId");
                ws.Date = reader.GetDateTime("Date");
                wsl.Add(ws);
           }
           reader.Close();
           return wsl;
      }
 }

Я хочу сделать этот код как можно более элегантно.

Для этого конкретного проекта я не могу использовать NHibernate на , как мне было поручено.



10665
6
задан 22 июля 2011 в 06:07 Источник Поделиться
Комментарии
2 ответа

Этот код очень тесно связаны с конкретной СУБД. Что делает его трудно изменить, если вы решите пойти с различными СУБД. И это не возможно для модульного тестирования вообще.

Вместо того, чтобы использовать специфические для MySQL-классы для соединений и т. д., изменить его использовать базовые интерфейсы, а затем передать соединения и запросы извне.

Кроме того, я вообще не использовать "возвращение" внутри блока кода, как "использование" и если/переключатель, если это не делает код слишком громоздкий. Таким образом, путь к коду намного легче следовать.

Ниже приведен пример этого конкретного метода в рамках одного класса, которые могут быть использованы в различных ситуациях, в т. ч. веб-страницы, сервисы и т. д. и с разными базами данных, Вт/o изменение осуществлении самого этого класса.

private IDatabaseProvider _dbProvider; //initialized in ctor, etc.
private IConnectionStringProvider _connectionStringProvider;
private IWebSiteMapper _mapper; //the db schema may change, or you may need to map from other source

public IList<WebSite> GetWebSitesForUser(int userId)
{
var wsl = new List<WebSite>();
var con = _dbProvider.GetNewConnection(); //returns IDbConnection
var cmd = _dbProvider.GetWebSiteListQueryCommand(con, userId); //IDbCommand, and addParam goes there

conn.Open(); // no need of try/catch or using, as if this fails, no resources are leaked
using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) //close con on reader.Close
{
while (reader.Read())
{
wsl.Add(_mapper.CreateFromReader(reader));
}
}

return wsl;
}

5
ответ дан 22 июля 2011 в 01:07 Источник Поделиться

Я бы


  • уменьшить видимость переменной ВСЛ как это не требуется за секунды , используя масштаб (если вы слушаете сверстников)

  • уменьшить видимость переменной г , а это не обязательно за первого используя масштаб

  • еще лучше, я бы, наверное, вообще воплощать строку запроса

  • инкапсулировать строительство связи (новый MySqlConnection(WebConfigurationManager.Выберите["MySqlConnectionString"].Метод toString())) в отдельную функцию параметр "createconnection" () в детали процесса не уместным в данном контексте. В параметр "createconnection" становится доступным для повторного использования и помогает вам, чтобы не повторяться

  • определить конструктор для экземпляра веб-сайта, особенно если все атрибуты являются обязательными сайта, например,'.Строитель().Идентификатор(читатель.getInt32("идентификатор").DomainUrl(...)...построить()'. Это позволит сделать его проще для вас, чтобы гарантировать, что каждый сайт имеет правильную форму.

  • отдельной итерации чтения и построения сайта

  • не устанавливаются освежения.Пользователей.Идентификатор , как это кажется неправильным для меня.

Это может выглядеть примерно так:

 using (MySqlConnection con = Connect())
{
string q = "select Id, DomainUrl, IsApproved, Date from website where UserId = @UserId";
using (MySqlCommand cmd = new MySqlCommand(q, con))
{
cmd.Parameters.Add("@UserId", MySqlDbType.Int32).Value = userId;
con.Open();

IList<WebSite> wsl = new List<WebSite>();
using(var reader = cmd.ExecuteReader()) {
foreach (WebSite webSite in CreateWebSites(reader))
{
wsl.Add(webSite);
}
}
return wsl;
}
}

private IEnumerable<WebSite> CreateWebSites(MySqlDataReader reader)
{
while (reader.Read())
{
yield CreateWebSite(reader);
}
}

private MySQLConnection Connect()
{
return new MySqlConnection(
WebConfigurationManager.ConnectionStrings["MySqlConnectionString"].
ToString());
}

private WebSite CreateWebSite(Reader reader)
{
return WebSite.Builder().
Id(reader.GetInt32("Id")).
DomainUrl(reader.GetString("DomainUrl")).
IsApproved(reader.GetBoolean("IsApproved")).
User(reader.GetInt32("UserId"))
Date(reader.GetDateTime("Date")).
Build();
}

Отказ от ответственности: я не знаю C# и вообще.

2
ответ дан 22 июля 2011 в 11:07 Источник Поделиться