Слой Доступа К Данным Код


Интересно, если я мог бы сделать это немного лучше. В настоящее время, мое ООО имеет пустой конструктор, который задает строку подключения из интернета.конфиг.

private string cnnString;

public DAL()
{
    cnnString = ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString;
}

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

public bool spInsertFeedback(string name, string subject, string message)
{
    int rows = 0;

    SqlConnection connection = new SqlConnection(cnnString);
    try
    {
        connection.Open();
        SqlCommand command = new SqlCommand("[dbo].[spInsertFeedback]", connection);
        command.CommandType = CommandType.StoredProcedure;

        // params
        SqlParameter messageName = new SqlParameter("@name", SqlDbType.VarChar);
        messageName.Value = name;
        SqlParameter messageSubject = new SqlParameter("@subject", SqlDbType.VarChar);
        messageSubject.Value = subject;
        SqlParameter messageText = new SqlParameter("@message", SqlDbType.VarChar);
        messageText.Value = message;

        // add params
        command.Parameters.Add(messageName);
        command.Parameters.Add(messageSubject);
        command.Parameters.Add(messageText);

        rows = command.ExecuteNonQuery();
    }
    catch
    {
        return (rows != 0);
    }
    finally
    {
        connection.Close();
    }

    return (rows != 0);
}

Очевидно, некоторые возвращают набор данных или списка объект или что-то, где в этот раз вернется ли какой-либо строки были затронуты.

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

DAL dal = new DAL();
bool success = dal.spInsertFeedback(name, subject, message);
return Json(success);

Спасибо, ребята.



9151
5
c#
задан 24 мая 2011 в 03:05 Источник Поделиться
Комментарии
6 ответов

Я бы не рекомендовал класть дал код на попробовать-поймать блок. По крайней мере, вы должны быть лесозаготовок или делать что-то об этом, сейчас ты просто возвращаем false (или отсутствие значения). Если исключение произойдет, пусть это случится, или поставить попробовать-поймать на функцию, которая вызывает его. Помните, что исключения Вары (сделал сервером БД остановить? был в SQL неправильный? это все разные случаи.)

Используя используя это лучшая практика для всех интерфейс IDisposable объекты, таким образом, принять его. Если вы запустите инструменты анализа кода в Visual студии (конечной редакции только я думаю) было бы также сказать вам, чтобы сделать так.

Моя версия код похож на Джеффа (который я хотел проголосовать, но не хватает рэп еще) с исключением, sqlcommand, который тоже одноразовые и могут/должны быть использованы с помощью блока.

public bool spInsertFeedback(string name, string subject, string message)
{
int rows = 0;
using (var connection = new SqlConnection(cnnString))
{
connection.Open();
using (var command = new SqlCommand("[dbo].[spInsertFeedback]", connection))
{
command.CommandType = CommandType.StoredProcedure;
// params
SqlParameter messageName = new SqlParameter("@name", SqlDbType.VarChar);
messageName.Value = name;
SqlParameter messageSubject = new SqlParameter("@subject", SqlDbType.VarChar);
messageSubject.Value = subject;
SqlParameter messageText = new SqlParameter("@message", SqlDbType.VarChar);
messageText.Value = message;

// add params
command.Parameters.Add(messageName);
command.Parameters.Add(messageSubject);
command.Parameters.Add(messageText);
rows = command.ExecuteNonQuery();
}
}
return (rows != 0);
}

Также я бы посоветовал вам использовать connectionString и вместо cnnString, что это не правильное именование.

4
ответ дан 25 мая 2011 в 09:05 Источник Поделиться

Я очень рекомендовал бы использование ORM вместо того, чтобы писать свой собственный даль, и вы будете гораздо более продуктивным программистом в целом. NHibernate и основы сущность являются хорошим выбором, или даже Linq2Sql если это небольшой проект, который не критическое для производительности. Таким образом, вы можете проводить время, решая проблемы, а не писать шаблонный код для "сантехника".

Это также открывает дверь для тестирования, которое не возможно с кода, который вы написали; использование ORM можно заменить структуры данных в памяти или глумится в ваш юнит-тесты для моделирования поведения на базе остальной части вашей программы. Это не возможно, когда вы используете sqlclient как пространство имен напрямую и опираясь на хранимые процедуры в базе данных.

3
ответ дан 25 мая 2011 в 03:05 Источник Поделиться

Вы можете перенести ваш попробовать / поймать / вернуть логику в отдельный метод, который принимает объект sqlcommand, который в качестве параметра.

Кроме того, поскольку вы используете только ваш finally блок, чтобы закрыть соединение, вы могли бы рассмотреть с помощью блока:

private bool runSpCommand (SqlCommand command)
{
int rows = 0;

using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
command.Connection = connection;
rows = command.ExecuteNonQuery();
// connection closed on following line, even if there's an exception
}

return (rows != 0);

}

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

Кроме того, в вызывающем коде, можно сделать так:

// params                
command.Parameters.Add("@name", SqlDbType.VarChar).Value = name;
command.Parameters.Add("@subject", SqlDbType.VarChar).Value = subject;
command.Parameters.Add("@message", SqlDbType.VarChar).Value = message;

1
ответ дан 24 мая 2011 в 05:05 Источник Поделиться

Я хотел превратить его в универсальный метод с этой подписью:

public bool ExecuteSp(string spName, List<MyParameter> parameters) {

// ...

SqlCommand command = new SqlCommand(spName, connection);

// ...

foreach(var p in parameters) {
SqlParameter sqlParameter = new SqlParameter(p.Name, p.Type);
sqlParameter.Value = p.Value;
command.Parameters.Add(p);
}
// ...
}

Использование ORM намного лучше, конечно.

1
ответ дан 25 мая 2011 в 03:05 Источник Поделиться

        SqlConnection connection = new SqlConnection(cnnString);

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

        catch
{
return (rows != 0);
}

Это очень злые три строки кода. Во-первых, вы ловите все исключения, которые собирается скрывать ошибки. Вы никогда не будете знать, если определенное исключение произошло. Во-вторых, вы носите в значительной степени игнорируя тот факт, что исключение произошло. Это очень очень плохо. НЕ ДЕЛАЙ ЭТОГО!

            SqlCommand command = new SqlCommand("[dbo].[spInsertFeedback]", connection);
command.CommandType = CommandType.StoredProcedure;

// params
SqlParameter messageName = new SqlParameter("@name", SqlDbType.VarChar);
messageName.Value = name;
SqlParameter messageSubject = new SqlParameter("@subject", SqlDbType.VarChar);
messageSubject.Value = subject;
SqlParameter messageText = new SqlParameter("@message", SqlDbType.VarChar);
messageText.Value = message;

// add params
command.Parameters.Add(messageName);
command.Parameters.Add(messageSubject);
command.Parameters.Add(messageText);

rows = command.ExecuteNonQuery();

Я думаю, что вы действительно хотите-это простой интерфейс для этого куска кода. Что-то вроде:

SQLProcedureCall insertFeedback = new SQLProcedureCall("[dbo].[spInsertFeedback]", connection);
insertFeedback.set("name", name);
insertFeedback.set("subject", subject);
insertFeedback.set("message", message);
return insertFeedback.Execute();

Вы должны быть в состоянии легко определить класс, который реализует это. Что повторений в эффективно устранены.

1
ответ дан 25 мая 2011 в 11:05 Источник Поделиться

Решение заменить этот код.... это перестать писать этот код.

Эти типы Далс отличная мишень для подъема на микро ОРМ. В Том Числе И Щеголь, Массивные, Простые.Данных, и PetaPoco, чтобы назвать несколько.

Лично я фанат PetaPoco самых. Он доступен через NuGet. У вас есть выбор ядра или полный, где полностью включает в себя шаблоны T4, которые позволяют создать модель из базы данных (не для меня, но некоторым людям это нравится) и сердечника (который является зависимость полного пакета) облегчает все ваши запросы.

0
ответ дан 26 мая 2011 в 05:05 Источник Поделиться