C# 在c中从db层调用存储过程#
假设你有一些简单的存储过程 AddXYZ(参数1、参数2…等) getAllXYZ() getXYZ(id) 从“db层”调用这些存储过程的“最佳实践”方式是什么 我不想使用linq。简单的c#静态方法就可以做到这一点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(
我正在使用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。