存储过程的通用数据访问代码,以返回Enumerable< >
本文关键字:返回 Enumerable 代码 数据 访问 存储过程 | 更新日期: 2023-09-27 18:05:09
与其用不同的Enumerable重复相同的ADO.net代码,我想让它更通用和可重用。
我有以下ADO。Net代码返回一个对象集合:
public static IEnumerable<TasCriteria> GetTasCriterias()
{
using (var conn = new SqlConnection(_connectionString))
{
var com = new SqlCommand();
com.Connection = conn;
com.CommandType = CommandType.StoredProcedure;
com.CommandText = "IVOOARINVENTORY_GET_TASCRITERIA";
var adapt = new SqlDataAdapter();
adapt.SelectCommand = com;
var dataset = new DataSet();
adapt.Fill(dataset);
var types = (from c in dataset.Tables[0].AsEnumerable()
select new TasCriteria()
{
TasCriteriaId = Convert.ToInt32(c["TasCriteriaId"]),
TasCriteriaDesc= c["CriteriaDesc"].ToString()
}).ToList<TasCriteria>();
return types;
}
}
模型:
public class TasCriteria
{
public int TasCriteriaId { get; set; }
public string TasCriteriaDesc { get; set; }
}
如果存储过程返回的列名与类中的属性完全匹配,则可以使用如下代码所示的反射。我将把向存储过程添加参数的练习留给其他人。(顺便说一下,这是未经测试的代码,我是凭脑子写的)
public static IEnumerable<T> GetStoredProcedure<T>(string procedure) where T : new()
{
var data = new List<T>();
using (var conn = new SqlConnection(_connectionString))
{
var com = new SqlCommand();
com.Connection = conn;
com.CommandType = CommandType.StoredProcedure;
com.CommandText = procedure;
var adapt = new SqlDataAdapter();
adapt.SelectCommand = com;
var dataset = new DataSet();
adapt.Fill(dataset);
//Get each row in the datatable
foreach (DataRow row in dataset.Tables[0].Rows)
{
//Create a new instance of the specified class
var newT = new T();
//Iterate each column
foreach (DataColumn col in dataset.Tables[0].Columns)
{
//Get the property to set
var property = newT.GetType().GetProperty(col.ColumnName);
//Set the value
property.SetValue(newT, row[col.ColumnName]);
}
//Add it to the list
data.Add(newT);
}
return data;
}
}
假设你有一个这样的类:
public class TasCriteria
{
public int TasCriteriaId { get; set; }
public string TasCriteriaDesc { get; set; }
}
你可以这样调用这个函数:
IEnumerable<TasCriteria> criteria = GetStoredProcedure<TasCriteria>("IVOOARINVENTORY_GET_TASCRITERIA");
可以选择从主方法中提取特定的代码。
在例子:public static IEnumerable<T> GetCriterias(
string storedProcedureName,
Func<IEnumerable<T>> enumerateMethod)
{
using (var conn = new SqlConnection(_connectionString))
{
var com = new SqlCommand();
com.Connection = conn;
com.CommandType = CommandType.StoredProcedure;
com.CommandText = storedProcedureName;
var adapt = new SqlDataAdapter();
adapt.SelectCommand = com;
var dataset = new DataSet();
adapt.Fill(dataset);
return enumerateMethod(dataset.Tables[0]);
}
}
如果你的存储过程需要参数,你可以重载你的函数:
public static IEnumerable<T> GetCriterias(
string storedProcedureName,
Func<IEnumerable<T>> enumerateMethod,
SqlParameter[] parameters)
使用此代码,您可以定义与de Func<>
签名匹配的方法。
public static IEnumerable<TasCriteria> EnumerateTasCriteria(DataTable table)
{
return
(from c in table.AsEnumerable()
select new TasCriteria()
{
TasCriteriaId = Convert.ToInt32(c["TasCriteriaId"]),
TasCriteriaDesc= c["CriteriaDesc"].ToString()
}).ToList<TasCriteria>();
}
public static IEnumerable<DetailCriteria> EnumerateDetailCriteriaCriteria(
DataTable table)
{
return
(from c in table.AsEnumerable()
select new DetailCriteria()
{
DetailCriteriaId = Convert.ToInt32(c["DetailCriteriaId"]),
DetailCriteriaDesc = c["CriteriaDesc"].ToString()
}).ToList<TasCriteria>();
}
然后,你可以这样调用你的代码:
IEnumerable<TasCriteria> task =
GetCriterias<TasCriteria>("IVOOARINVENTORY_GET_TASCRITERIA", EnumerateTasCriteria);
IEnumerable<DetailCriteria> details =
GetCriterias<DetailCriteria>("IVOOARINVENTORY_GET_DETAILSCRITERIA", EnumerateDetailCriteriaCriteria);