вызов sprocs из слоя БД в c # - PullRequest
0 голосов
/ 15 июня 2009

предположим, у вас есть несколько простых звездочек, например

AddXYZ (параметр 1, параметр 2 ... и т. Д.)

getAllXYZ ()

getXYZ (ID)

каков наилучший способ вызова этих sprocs из "db layer"

я не хочу использовать linq. просто c # статические методы о том, как это сделать.

я использую sqlserver.

Ответы [ 5 ]

8 голосов
/ 15 июня 2009

Я не думаю, что вы на самом деле имели в виду static методы, так как это было бы довольно не ОО-способом примерно так, и в C # таких средств нет. Однако существуют стандартные классы ADO.NET, которые позволят вам сделать это без использования ORM или использования DataSet и т. П. -

Если вы действительно хотите вручную запустить сохраненный процесс и получить набор результатов без ЛЮБОГО ORM или стандартизированного механизма хранения, сделавшего это за вас, это будет вашим лучшим выбором:

using(System.Data.IDbConnection conn = /*create your connection here*/)
{
    using(System.Data.IDbCommand cmd = conn.CreateCommand())
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "AddXYZ";

        // add your parameters here using cmd.CreateParameter() and cmd.Parameters.Add()

        using(System.Data.IDbDataReader reader = cmd.ExecuteReader())
        {
            while(reader.Read())
            {
                // read your results row-by-row
            }
        }
    }
}

Вы не указали, через какой движок базы данных вы подключаетесь, поэтому я использовал общие интерфейсы, которые отвлекут вас от этого. Если вы хотите (хотя я обычно хмурится на код, который делает это), вы можете использовать платформо-зависимые классы, которые упрощают работу, по крайней мере, с точки зрения добавления параметров (код не такой подробный, как подход на основе интерфейса) 1008 *

5 голосов
/ 15 июня 2009

Это то, что вы ищете?

SqlCommand cmd  = new SqlCommand("AddXYZ", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@param1", someValue));
1 голос
/ 15 июня 2009

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

private static ConnectionString { get { // read from config file once.... return ""; } }

private SqlConnection getConnection()
{
    SqlConnection result = new SqlConnection(ConnectionString);
    result.Open();  // I like to open it in advance, but that's less common
    return result;  // you'll want some error handling code in here as well
}

Затем вы предоставляете открытые методы на уровне данных, которые соответствуют интерфейсу, который вы хотите предоставить бизнес-уровню. В хорошо разработанном приложении это обычно будет соответствовать хранимым процедурам, и это звучит как то, что вы собираетесь, но иногда это не совсем хорошо работает. Например, вам может потребоваться вызвать несколько процедур из одного метода.

Что бы вы ни делали, метод должен принимать строго типизированные значения параметров для использования при вызове процедур. Есть некоторые споры о том, должен ли метод возвращать бизнес-объект или корд данных. Лично я склоняюсь к тому, чтобы возвращать шнур данных, но предоставляю дополнительный «слой», где строки данных транслируются в строго типизированные бизнес-объекты:

public IDataRecord GetXYZ(int id)
{
    DataTable dt = new DataTable();
    using (var cn = getConnection())
    using (var cmd = new SqlCommand("getXYZ"))
    {
        cmd.CommandType = CommandTypes.StoredProcedure;
        cmd.Parameters.Add("@ID", SqlDbType.Int).Value = id;

        using (var rdr = cmd.ExecuteReader())
        {
           dt.Load(rdr);
        }
    }

    //obviously put a little more work into your error handling
    if (dt.Rows.Count <= 0)
       throw new Exception("oops");  

    return dt.Rows[0];
}

public class XYZFactory
{
    public static XZY Create(IDataRecord row)
    {
        XYZ result = new XYZ();
        result.id = row["ID"];
        result.otherfield = row["otherfield"];
        return result;
    }
}
0 голосов
/ 15 июня 2009

Пример Томаса - стандартный способ. Я предлагаю вам взглянуть на следующее для получения дополнительной помощи:

http://msdn.microsoft.com/en-us/library/aa902662.aspx

Лично я написал статический класс (DataHelper), который предоставляет кучу методов, которые вы, вероятно, будете использовать, например, те, которые возвращают объекты IDataReader, когда ваш сохраненный процесс возвращает вещи, и методы void, когда они это делают. нет, а также некоторые, которые возвращают объект Connection в выходном параметре, чтобы вы могли оставить его открытым.

Класс просто оборачивает код ADO.NET в блоки try catch для проверки общих проблем и ведения журнала / трассировки (отключение DNS, отключение сервера, отключение svc) и использует оператор using для гарантии того, что ресурсы не будут потрачены впустую. Я также обертываю метод, который использует ConnectionStringBuilder для возврата строки подключения, поэтому мне не нужно продолжать писать этот код.

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

В наши дни, если бы у меня было зеленое поле, я бы посмотрел на использование EDM.

http://msdn.microsoft.com/en-us/library/aa697428(VS.80).aspx

0 голосов
/ 15 июня 2009

В общем, вы захотите взглянуть на классы SQLConnection и SQLCommand (конечно, при условии, что вы подключаетесь к базе данных SQL). Вы установите для свойства SQLCommand.CommandText что-то вроде «EXEC AddXYZ @X, @Y, @Z», а затем будете использовать SQLCommand.Parameters.AddWithValue () для каждого из @X, @Y и @ Z.

Затем вы вызовете соответствующий метод execute вашего SQLCommand (NonQuery, Scalar или Reader).

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