C# 将DataTable转换为List,其中List的类是动态的
我正在从C代码执行一个存储过程C# 将DataTable转换为List,其中List的类是动态的,c#,list,datatable,C#,List,Datatable,我正在从C代码执行一个存储过程 private void DataToGrid() { DataTable dt = new DataTable(); string[,] aryPara = new string[,] {{ "@pClassId", "10" } , { "@pMediumId", "11" } , { "@pStreamId", "12" } , { "@pSessionId","13" } , { "@pSectio
private void DataToGrid()
{
DataTable dt = new DataTable();
string[,] aryPara = new string[,]
{{ "@pClassId", "10" } ,
{ "@pMediumId", "11" } ,
{ "@pStreamId", "12" } ,
{ "@pSessionId","13" } ,
{ "@pSectionId", "15" } ,
{ "@pShiftId", "16" } ,
{ "@pDateId", "17" } };
dt = CallStoredProcedureUsingAdapterFillDataTabel("ssspAtdDailyattendance", aryPara);
DatagridView1.DataSource = dt;
}
public DataTable CallStoredProcedureUsingAdapterFillDataTabel(string StoredProcedureName, [Optional] string[,] aryParameters)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = "Data Source=AIS-OCTACORE\SQLserver2008r2;Initial Catalog= SchoolSoulDataTest; integrated security=SSPI";
con.open();
SqlCommand lSQLCmd = new SqlCommand();
SqlDataAdapter adp = new SqlDataAdapter();
DataTable dt = new DataTable();
lSQLCmd.CommandType = CommandType.StoredProcedure;
lSQLCmd.CommandText = StoredProcedureName;
lSQLCmd.CommandTimeout = 300;
try
{
for (int i = 0; i < aryParameters.GetLength(0); i++)
{
lSQLCmd.Parameters.Add(new SqlParameter(aryParameters[i, 0], aryParameters[i, 1]));
}
}
catch (Exception ex)
{
}
lSQLCmd.Connection = con;
adp.SelectCommand = lSQLCmd;
adp.Fill(dt);
clsConnectionClose();
return dt;
}
其中,ssspattdailyattendance是一个动态存储过程,其中存储过程返回的数据具有可变的列数
现在我想将DataTable dt转换为一个列表,但由于dt返回可变的列数,所以T的类型不是固定的
所以我的问题是如何将dt转换为List?我建议您使用Dapper,而不是自己编写和维护样板代码。Dapper支持动态对象
执行查询并将其映射到动态对象列表
网站:
NuGet:如果我正确理解你的问题,T可以是多种类型 例如,第一排可能是人,第二排可能是狗?或者你指的是不同的类型,比如字符串、整型、日期等值类型 不管怎样,您都需要创建T实体来表示datatable中的数据并对其进行映射 您正在寻找的可能是ValueInjector或Automapper之类的映射器 甚至: 这里显示了如何使用将DataTable映射到类。它可以给你一个开始
我希望这能有所帮助。根据您发布的答案,您可以使用以下内容:
IList<Class1> items = dt.AsEnumerable().Select(row =>
new Class1
{
id = row.Field<string>("id"),
name = row.Field<string>("name")
}).ToList();
然后你可以调用函数作为
IList<Class1> items = dt.AsEnumerable().Select(row => new Class1(row)).ToList();
我面对这个问题,必须使用来自 他有一个相关的问题。如果只有类型不同,那么如果没有公共字段,并且实现其他字段的不同类型,则可以通过公共字段或对象的接口轻松解决这一问题。构建列表时,使用工厂决定为行或wholde数据表构建哪种类型,然后使用行构建对象 但是,如果类型在编译时未知,则有许多解决方案: 将DLR与dynamic关键字一起使用。 ExpandoObject可以执行您需要的操作。 像使用字典一样使用hashmap 使用Emit框架发出类型。 这个解决方案实际上很复杂,它将引导您使用CLR的高级部分。然而,这确实很有效。 如果你选择这条路,这将对你大有帮助。 对于你的需求来说,这可能是过分的。
可能还有其他解决方案。祝您选择的解决方案好运。我不明白我是如何做到这一点的。您能简单地编写代码吗?只需使用Dapper执行存储过程,而不是自己直接使用SqlCommand。
IList<Class1> items = dt.AsEnumerable().Select(row =>
new Class1
{
id = row.Field<string>("id"),
name = row.Field<string>("name")
}).ToList();
public class Class1
{
private int id;
public string name;
public Class1(DataRow row)
{
id = (int)GetColumnValue(row, "id");
name = (string)GetColumnValue(row, "name");
}
public object GetColumnValue(DataRow row, string column)
{
return row.Table.Columns.Contains(column) ? row[column] : null;
}
}
IList<Class1> items = dt.AsEnumerable().Select(row => new Class1(row)).ToList();
public static class HelperExtensions
{
public static List<dynamic> ToDynamic(this DataTable dt)
{
var dynamicDt = new List<dynamic>();
foreach (DataRow row in dt.Rows)
{
dynamic dyn = new ExpandoObject();
dynamicDt.Add(dyn);
foreach (DataColumn column in dt.Columns)
{
var dic = (IDictionary<string, object>)dyn;
dic[column.ColumnName] = row[column];
}
}
return dynamicDt;
}
}