C# 在c中从db层调用存储过程#

C# 在c中从db层调用存储过程#,c#,database,stored-procedures,C#,Database,Stored Procedures,假设你有一些简单的存储过程 AddXYZ(参数1、参数2…等) getAllXYZ() getXYZ(id) 从“db层”调用这些存储过程的“最佳实践”方式是什么 我不想使用linq。简单的c#静态方法就可以做到这一点 我正在使用sqlserver。这就是您要找的吗 SqlCommand cmd = new SqlCommand("AddXYZ", conn); cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add(

假设你有一些简单的存储过程

AddXYZ(参数1、参数2…等)

getAllXYZ()

getXYZ(id)

从“db层”调用这些存储过程的“最佳实践”方式是什么

我不想使用linq。简单的c#静态方法就可以做到这一点


我正在使用sqlserver。

这就是您要找的吗

SqlCommand cmd  = new SqlCommand("AddXYZ", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@param1", someValue));

这就是你要找的吗

SqlCommand cmd  = new SqlCommand("AddXYZ", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@param1", someValue));

一般来说,您需要查看SQLConnection和SQLCommand类(当然,假设您正在连接到一个sqldb)。将SQLCommand.CommandText属性设置为类似“EXEC AddXYZ@X、@Y、@Z”的值,然后对@X、@Y和@Z中的每一个使用SQLCommand.Parameters.AddWithValue()


然后,您将调用SQLCommand相应的执行方法(非查询、标量或读取器)。

一般来说,然后,您将需要查看SQLConnection和SQLCommand类(当然,假设您正在连接到SQL db)。将SQLCommand.CommandText属性设置为类似“EXEC AddXYZ@X、@Y、@Z”的值,然后对@X、@Y和@Z中的每一个使用SQLCommand.Parameters.AddWithValue()


然后您将调用SQLCommand相应的执行方法(非查询、标量或读取器)。

我不认为您真正指的是
静态
方法,因为这将是一种非常非OO的方式来处理类似的事情,而且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
            }
        }
    }
}

您没有指定要通过哪个数据库引擎进行连接,所以我使用了公共接口,将您从中抽象出来。如果您愿意(尽管我通常不赞成这样做的代码),您可以使用特定于平台的类,使事情稍微容易一些,至少在添加参数方面(代码没有基于接口的方法那么详细)

我认为您不是指静态方法,因为这将是一种非常非OO的方式来处理类似的事情,而且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
            }
        }
    }
}

您没有指定要通过哪个数据库引擎进行连接,所以我使用了公共接口,将您从中抽象出来。如果您愿意(尽管我通常不赞成这样做的代码),您可以使用特定于平台的类,使事情稍微容易一些,至少在添加参数方面(代码没有基于接口的方法那么详细)

首先,您可以在数据层中创建一个位置来获取连接信息。如果数据层仅限于一个类,则该成员可能是私有成员;如果该层包含整个程序集,则该成员可能是内部项。它可以返回一个连接字符串或一个实际的连接对象本身,但最主要的是它根本不会暴露在数据层之外:

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;
    }
}
public-IDataRecord-GetXYZ(int-id)
{
DataTable dt=新的DataTable();
使用(var cn=getConnection())
使用(var cmd=new SqlCommand(“getXYZ”))
{
cmd.CommandType=CommandTypes.storedProcess;
cmd.Parameters.Add(“@ID”,SqlDbType.Int).Value=ID;
使用(var rdr=cmd.ExecuteReader())
{
dt.荷载(rdr);
}
}
//显然,要在错误处理上多做一些工作

如果(dt.Rows.Count首先,在数据层中创建一个位置以获取连接信息。如果数据层仅限于一个类,则该位置可能是私有成员;如果层包含整个程序集,则该位置可能是内部项。它可以返回连接字符串或实际的连接对象本身,但主要是至少,它不会暴露在数据层之外:

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;
    }
}
public-IDataRecord-GetXYZ(int-id)
{
DataTable dt=新的DataTable();
使用(var cn=getConnection())
使用(var cmd=new SqlCommand(“getXYZ”))
{
cmd.CommandType=CommandTypes.storedProcess;
cmd。