怎么做,在Complex DataTable

时间:2016-12-22 05:38:58

标签: c# asp.net datatable system.reflection

我在Home Controller中有一个DataTable,如下所示:

public DataTable GetTable()
{
    DataTable table = new DataTable();
    table.Columns.Add("Dosage", typeof(int));
    table.Columns.Add("Drug", typeof(string));
    table.Columns.Add("Patient", typeof(Info));
    table.Columns.Add("Date", typeof(DateTime));

    table.Rows.Add(25, "Indocin", new Info("India"), DateTime.Now);
    table.Rows.Add(50, "Enebrel", new Info("UK"), DateTime.Now);
    table.Rows.Add(10, "Hydralazine", new Info("Bhutan"), DateTime.Now);
    table.Rows.Add(21, "Combivent", new Info("India"), DateTime.Now);
    table.Rows.Add(100, "Dilantin", new Info("GreenLand"), DateTime.Now);
    return table;
}

信息类如下

public class Info
{
    public string Address { get; set; }
    public Info(string Add) {
        this.Address = Add;
    }
}

现在,我想基于地址字段进行过滤操作,即Patient.Address

此处,患者是Info类的对象

我获取了有关每列的信息,如下所示我在方法“DataTableExtensions.DataTableSerialize(data)”中定义了功能

DataTableExtensions.DataTableSerialize(data)
Count = 4
    [0]: {[Dosage, System.Nullable`1[System.Int32]]}
    [1]: {[Drug, System.String]}
    [2]: {[Patient, MvcApplication66.Controllers.HomeController+Info]}
    [3]: {[Date, System.Nullable`1[System.DateTime]]}

但是,我需要根据Patient.Address过滤DataTable

我在下一行中收到了错误。

DataTableExtensions.DataTableSerialize(data)[ColumnName]
  

未处理的类型异常   发生'System.Collections.Generic.KeyNotFoundException'   mscorlib.dll中

     

附加信息:给定的密钥不在   字典。

我犯了错误。

是否可以在复杂数据表中执行过滤操作。

2 个答案:

答案 0 :(得分:1)

复杂数据表可以被过滤,我已经形成了这个要求的谓词。

var memberNames = memberPath.Split('.');
Expression value = Expression.Call(
    typeof(DataRowExtensions), "Field", new Type[] { columnType },
    source, Expression.Constant(memberNames[0]));
for (int i = 1; i < memberNames.Length; i++)
    value = Expression.PropertyOrField(value, memberNames[i]);
return value;

最后谓语形成为 bExp = {(DataRow.Field(“Patient”)。Address.ToLower()==“india”)}

所以,查询字符串将为 data = {System.Data.EnumerableRowCollection`1 [System.Data.DataRow] .Where(DataRow =&gt;(DataRow.Field(“Patient”)。Address.ToLower()==“india”))}

现在,我可以获取数据。

更多详情:请参阅以下链接

How to create (predicate) for fetching data from DataTable using Express.call method

答案 1 :(得分:0)

您可以使用Linq

过滤DataTable
//fill the datatable
DataTable dt = GetTable();

//filter the datatable with Linq
var filteredRows = dt.AsEnumerable().Where(x => x.Field<Info>("Patient").Address == "India");

//check if there are any rows before calling CopyToDataTable,
//otherwise you'll get a "The source contains no DataRows" error
if (filteredRows.Any())
{
    DataTable dtFiltered = filteredRows.CopyToDataTable();
}

如果您100%确定过滤后的表格中包含行,则可以直接致电CopyToDataTable()

DataTable dtFiltered = dt.AsEnumerable().Where(x => x.Field<Info>("Patient").Address == "Bhutan").CopyToDataTable();

但我建议您从DataTable To Lists中进行更改,以后Info变得更复杂时,这会更容易。

List<Drugs> patients = new List<Drugs>();

public class Drugs
{
    public int Dosage { get; set; }
    public string Drug { get; set; }
    public Info Patient { get; set; }
    public DateTime Date { get; set; }
}