循环访问DataTable并仅选择

时间:2015-08-04 08:43:01

标签: c# dictionary datatable

我有一个DataTable,我想循环遍历每一行和每列,然后根据列/每行中的其他值从特定列中选择一个值。

我的代码目前看起来像这样:

 foreach (DataRow drow in dt.Rows)
 {
     foreach (DataColumn dcol in dt.Columns)
     {
         foreach (var Item in ImportData)
         {
             if (Item.Value.Equals(true))
             {
                 if (Item.Key.Equals("" + dcol))
                 {
                     string value = drow[dcol].ToString();
                     if (value.Equals("X"))
                     {
                         outDraws += drow["Drawing"].ToString();
                         outDraws += "\n";
                     }
                 }
             }
         }
     }
}

ImportData是Dictionary<string, bool>,它保存我想要与我的DataTable进行比较的数据。

string outDraws只是一个字符串,应该包含我要打印的图纸的内容。

我现在的问题是我只想打印出行的“绘图”列中的内容,其中所有与ImportData中的键同名的列都以“X”作为值。目前,我得到的所有行都是“X”作为值,并且与ImportData中的任何键具有相同的名称。

我知道你很难得到我想做的事,但请问你是否需要更多信息,我会尽力提供。

非常感谢提前。

修改:

ImportData包含不同产品的名称作为键。客户通过其他程序选择或不选择这些产品,如果已选择它们,则它们的值为true,如果未选择,则它们的值为false。

使用上面介绍的方法,我想将所有值为true的键与DataTable中的列名进行比较。如果列名对应于ImportData中的键(这是产品的名称),那么我想检查特定行中的列是否有'X'作为值。

这继续导入ImportData中的所有键,最后我应该知道DataTable中哪一行在所有列中都有一个'X',其名称与ImportData中的键相同。对于这一行,我想获得名为“Drawing”的列的内容。 因此,举个例子说ImportData包含:

[Motor,true] [Product6,true] [Product7,true]

然后我想在第6行打印出绘图栏。

不幸的是我无法发布图片..

2 个答案:

答案 0 :(得分:0)

试试这个

class baseClass
{
public:
    virtual void foo();
}

class derivedClass : public baseClass
{
protected:
    virtual void foo() override;
}

答案 1 :(得分:0)

与任何问题一样:分而治之。以较小的碎片分解您的问题并从那里开始。

据我所知,您希望对数据表中的某些行执行某些操作。类似的东西:

 foreach (var drow in dt.Rows.OfType<DataRow>())
 {
     if (SomeConditionIsMet(dt, drow, ImportData))
     {
         outDraws += drow["Drawing"].ToString();
         outDraws += "\n";
     }
 }

SomeConditionIsMet函数可能如下所示:

private static bool SomeConditionIsMet(
                         DataTable dt, DataRow drow, 
                         IDictionary<string, bool> importData)
{
   // TODO if the condition is met, return true
   // otherwise, return false
}

现在,您的问题被简化为思考其意味着什么条件得到满足&#39;。一旦您可以用文字清楚地表达,重命名该功能以反映该功能(例如,以及#39; AllColumnsAreChecked&#39;)

以下是我理解的解决方案示例:

internal class Program
{
    private static void Main(string[] args)
    {
        var importData = new Dictionary<string, bool>()
        {
            {"Product1", true},
            {"Product2", false},
            {"Product3", true},
        };

        var dt = new DataTable();
        dt.Columns.Add("Product1");
        dt.Columns.Add("Product2");
        dt.Columns.Add("Product3");
        dt.Columns.Add("Product4");
        dt.Columns.Add("Drawing");

        // row1 should be added
        var row1 = dt.NewRow();
        row1["Product1"] = "X";
        row1["Product3"] = "X";
        row1["Drawing"] = "Drawing1";
        dt.Rows.Add(row1);

        // row2 should not be added
        var row2 = dt.NewRow();
        row2["Product1"] = "X";
        row2["Drawing"] = "Drawing2";
        dt.Rows.Add(row2);

        string outDraws = string.Empty;

        foreach (DataRow drow in dt.Rows.OfType<DataRow>())
        {
            if (AllColumnsAreChecked(drow, importData))
            {
                outDraws += drow["Drawing"].ToString();
                outDraws += "\n";
            }
        }

        Console.WriteLine(outDraws);
    }

    private static bool AllColumnsAreChecked(DataRow drow, Dictionary<string, bool> importData)
    {
        foreach (var key in importData.Keys)
        {
            if (!importData[key])
                continue;
            var value = drow[key] as string;
            if (value != "X")
                return false;
        }
    }
}

Bonus:这是基于LINQ的检查实现:

    private static bool AllColumnsAreChecked(DataRow drow, Dictionary<string, bool> importData)
    {
        return importData.Keys
            .Where(k => importData.ContainsKey(k) && importData[k]) // the field must be enabled in importData
            .All(k => (drow[k] as string) == "X"); // the corresponding value in the row must be 'X'
     }