每行迭代n列

时间:2016-01-07 10:06:34

标签: c# .net

我有以下代码。为了解释'tl'变量将始终存在值。 目前它的硬编码总是假定行中有4列,但我想根据列的数量使其工作并使其根据有多少列构建级别,但是还需要一个列中的值。

所以目前如果第2列中有值,它将构建'ltwo'变量,然后如果第3列中有值,则执行'lthree'。 我想让它构建尽可能多的级别,以便不重复代码并反复使用相同的代码。

public static List<AdditionalPropertyType> SQLAddPropsStructured(DataTable dataTable, List<AdditionalPropertyType> currentadditionalproperties)
{
    foreach (DataRow row in dataTable.Rows)
    {
        var tl = new AdditionalPropertyType
        {
            Name = row[0].ToString(),
            Value = row[1].ToString()
        };

        if (!String.IsNullOrEmpty(row[2].ToString()))
        {
            var ltwo = new AdditionalPropertyType
            {
                Name = row[2].ToString()
            };
            var ltwolist = new List<AdditionalPropertyType>();
            ltwolist.Add(tl);
            ltwo.AdditionalProperties = ltwolist;

            if (!String.IsNullOrEmpty(row[3].ToString()))
            {
                var lthree = new AdditionalPropertyType
                {
                    Name = row[3].ToString()
                };
                var lthreelist = new List<AdditionalPropertyType>();
                lthreelist.Add(ltwo);
                lthree.AdditionalProperties = lthreelist;

                currentadditionalproperties.Insert(0, lthree);
            }
            else
                currentadditionalproperties.Insert(0, ltwo);
        }
        else
            currentadditionalproperties.Insert(0, tl);
    }
    return currentadditionalproperties;
}

3 个答案:

答案 0 :(得分:1)

您可以使用DataTable的Columns属性获取列:

foreach (DataRow row in dataTable.Rows)
{
    foreach(DataColumn column in dataTable.Columns)
    {
        Trace.WriteLine(column.ColumnName + " = " + row[column]);
    }
}

你可能想做这样的事情:(写在网站上,可能会出现一些小错字)

您需要迭代其他列并检查是否存在值。如果有值,请创建备用引用并续订您的属性。

public static List<AdditionalPropertyType> SQLAddPropsStructured(DataTable dataTable, List<AdditionalPropertyType> currentadditionalproperties)
{
    // check if there are atleast 2 columns defined
    if(dataTable.Columns.Count < 2)
        throw new Exception("At least two columns are required");

    // The result
    var currentadditionalproperties = new List<AdditionalPropertyType>();

    // iterate the rows
    foreach (DataRow row in dataTable.Rows)
    {
        // create the base property
        var tl = new AdditionalPropertyType
        {
            Name = row[0].ToString(),
            Value = row[1].ToString()
        };

        // check the rest of the columns for additional names
        foreach(int index=2;index<dataTable.Columns.Count;index++)
        {
            var columnValue = row[index].ToString();

            // if the column is empty, discontinue the iteration
            if(String.IsNullOrEmpty(columnValue))
                break;

            // create a backup reference.
            var previous = tl;

            // create a new AdditionalPropertyType
            var tl = new AdditionalPropertyType { Name = columnValue };
            // Create the list
            tl.AdditionalProperties = new List<AdditionalPropertyType>();
            // add the previous (backup reference)
            tl.AdditionalProperties.Add(previous);
        }
        // insert the 'chain' of additional properties on the list at possition 0
        currentadditionalproperties.Insert(0, tl);
    }
    // return the list
    return currentadditionalproperties;
}

答案 1 :(得分:0)

您尚未发布所有代码,因此我不得不猜测几个地方(例如“currentAdditionalProperties”的内容)。

我认为下面的代码通过使逻辑可扩展来说明您想要做什么,具体取决于数据表的列数。

诀窍是将“最后的东西”存储在变量中,因此它可以用于“当前事物”。最后,无论“最后一件事”是什么,都要存储在“currentAdditionalProperties”对象中。我评论过,你可以看到逻辑。

    private List<AdditionalPropertyType> SQLAddPropsStructured(DataTable dataTable)
    {
        AdditionalPropertyType lastNewType;             // to remember the previous new instance

        // for all rows...
        foreach (DataRow row in dataTable.Rows)
        {
            // the first type takes name and value from the first two fields
            AdditionalPropertyType newType = new AdditionalPropertyType();
            newType.Name = row[0].ToString();
            newType.Value = row[1].ToString();

            // remember this type: it is used as the AdditionalProperties for the NEXT type
            lastNewType = newType;

            // additional types start from field 2
            int field = 2;

            // iterate until we find a NULL  field.
            // If you want to check for the end of the fields rather than a NULL value, then instead use:
            //      while(field < dataTable.Columns.Count)
            while(!String.IsNullOrEmpty(row[field].ToString()))
            {
                // create new type
                var newSubType = new AdditionalPropertyType();

                // get name
                Name = row[field].ToString();

                // new type takes the PREVIOUS type as its additional parameters
                List<AdditionalPropertyType> propertyData = new List<AdditionalPropertyType>();
                propertyData.Add(lastNewType);
                newSubType.AdditionalProperties = propertyData;

                // remember THIS type for the NEXT type
                lastNewType = newSubType;

                // process next field (if valid)
                field++;
            }


            // put the last set of properties found into the current properties
            currentAdditionalProperties.Insert(0, lastNewType);
            return currentAdditionalProperties;
        }
    }

答案 2 :(得分:0)

第一步是撤消您的情况并使用关键字继续

public static List<AdditionalPropertyType> SQLAddPropsStructured(DataTable dataTable, List<AdditionalPropertyType> currentadditionalproperties)
{
    foreach (DataRow row in dataTable.Rows)
    {
        var tl = new AdditionalPropertyType
        {
            Name = row[0].ToString(),
            Value = row[1].ToString()
        };

        if (String.IsNullOrEmpty(row[2].ToString())){
             currentadditionalproperties.Insert(0, tl);
             continue;
        }

        var ltwo = new AdditionalPropertyType
        {
            Name = row[2].ToString()
        };
        var ltwolist = new List<AdditionalPropertyType>();
        ltwolist.Add(tl);
        ltwo.AdditionalProperties = ltwolist;

        if (String.IsNullOrEmpty(row[3].ToString())) {
            currentadditionalproperties.Insert(0, ltwo);
            continue;
        }

        var lthree = new AdditionalPropertyType
        {
            Name = row[3].ToString()
        };
        var lthreelist = new List<AdditionalPropertyType>();
        lthreelist.Add(ltwo);
        lthree.AdditionalProperties = lthreelist;

        currentadditionalproperties.Insert(0, lthree);                                            
    }
    return currentadditionalproperties;
}

现在,代码更清晰了。下一步是收集重复个案。请注意,第二种情况是重复。因此,做进一步的简化:

public static List<AdditionalPropertyType> SQLAddPropsStructured(DataTable dataTable, List<AdditionalPropertyType> currentadditionalproperties)
{
    foreach (DataRow row in dataTable.Rows)
    {
        var tlprev = new AdditionalPropertyType
        {
            Name = row[0].ToString(),
            Value = row[1].ToString()
        };

        bool isTlUpdated = true;
        for (int i = 2; i <= 3; ++i) { //change this according to your need
            if (String.IsNullOrEmpty(row[i].ToString()) && isTlUpdated){
                currentadditionalproperties.Insert(0, tlprev);
                isTlUpdated = false;
                break; //note that this will now change to break to break from the current for-loop
            }

            var lnext = new AdditionalPropertyType
            {
                Name = row[i].ToString()
            };
            var lnextlist = new List<AdditionalPropertyType>();
            lnextlist.Add(tlprev);
            lnext.AdditionalProperties = lnextlist;
            tlprev = lnext; //need to record this for the next loop or end of the case
            isTlUpdated = true;
        }

        if (isTlUpdated) //correction by Jeroen
            currentadditionalproperties.Insert(0, tlprev);                                            
    }
    return currentadditionalproperties;
}

关键是逐步简化代码