对于条件上的数据表的循环

时间:2015-06-04 12:03:27

标签: c# sql linq ado.net

我有一个结果数据集,

  

数据集dsResult = new Dataset();

dsResult.Tables [0] .Rows.Count = 17

现在我想在前5行的数据表中循环并创建一个dsResult.Tables [1]

然后接下来5行到dsResult.Tables [2]

以及接下来的5个dsResult.Tables [3]

然后最后两行到dsResult.Tables [4]

从下面的代码我得到了所需的表数

  

decimal remainder = Decimal.Divide(dsResult.Tables [0] .Rows.Count,5);         var numberOfRequests = Math.Ceiling((decimal)remainder);

或者我们可以在SQL

中完成

如何对这种逻辑进行一般化。

请在这里指导我。

4 个答案:

答案 0 :(得分:1)

使用Linq这很简单

var firstFive = dsResult.Tables[0].AsEnumerable().Take(5);
var secondFive = dsResult.Tables[0].AsEnumerable().Skip(5).Take(5);

等等。
不要循环,让Linq为你做。

如果以后需要将结果转换为数据表,MSDN就如何将结果转换为非常好的示例 Creating a DataTable From a Query (LINQ to DataSet)

答案 1 :(得分:0)

也许有帮助,但我不建议在实际项目中使用此解决方案。

// size of chunk
int chunkSize = 5;

// dataset and table variables
DataSet ds = GetDataSet();  // get your DataSet from somewhere
DataTable source = ds.Tables[0], dest;

// total rows
int count = ds.Tables[0].Rows.Count;
int tableCount = (count + 1) / chunkSize;

// create tables (copy structure)
for (int i = 0; i < tableCount; i++)
{
    dest = source.Clone();
    dest.TableName = source.TableName + "_" + i.ToString();
    ds.Tables.Add(dest);
}

// fill tables
int index = 0;
foreach (DataRow row in source.Rows)
{
    dest = ds.Tables[1 + index++ / chunkSize];

    // copy row (via copying item arrays)
    DataRow rowCopy = dest.NewRow();
    rowCopy.ItemArray = row.ItemArray;
    dest.Rows.Add(rowCopy);
}

答案 2 :(得分:0)

使用ChunkReader<T>的另一种解决方案(将列表切割为具有固定长度的部分的类)

<强> ChunkReader

using System;
using System.Collections.Generic;
using System.Linq;

namespace ServiceCore.Helpers
{
    /// <summary>
    /// чанкер
    /// </summary>
    public class ChunkReader<T>
    {
        #region Declarations

        private List<T> _data;                  // данные
        private int _pos;                       // позиция

        #endregion
        #region Properties

        /// <summary>
        /// число записей
        /// </summary>
        public int Count { get { return _data.Count; } }

        /// <summary>
        /// размер чанка
        /// </summary>
        public int ChunkSize { get; set; }

        /// <summary>
        /// число чанков
        /// </summary>
        public int ChunksCount
        {
            get
            {
                int count = _data.Count;
                return count == 0 ? 0 : (int)Math.Ceiling((double)count / (double)ChunkSize);
            }
        }

        #endregion

        #region Constructors

        /// <summary>
        /// конструктор
        /// </summary>
        public ChunkReader()
        {
            ChunkSize = 20;
        }

        /// <summary>
        /// конструктор
        /// </summary>
        /// <param name="data"> данные </param>
        public ChunkReader(List<T> data)
            : this()
        {
            Init(data);
        }

        /// <summary>
        /// конструктор
        /// </summary>
        /// <param name="data"> данные </param>
        /// <param name="chunkSize"> размер чанка </param>
        public ChunkReader(List<T> data, int chunkSize)
            : this()
        {
            ChunkSize = chunkSize;
            Init(data);
        }

        #endregion

        #region Private methods
        #endregion
        #region Protected methods
        #endregion
        #region Public methods

        /// <summary>
        /// инициализация
        /// </summary>
        /// <param name="data"> данные </param>
        public void Init(List<T> data)
        {
            _data = data;
            _pos = 0;
        }

        /// <summary>
        /// сбросить текущую позицию
        /// </summary>
        public void Reset()
        {
            _pos = 0;
        }

        /// <summary>
        /// прочитать очередной чанк
        /// </summary>
        /// <param name="chunk"> чанк </param>
        /// <returns></returns>
        public bool Read(out List<T> chunk)
        {
            int count = _data.Count;
            if (_pos >= count)
            {
                chunk = null;
                return false;
            }
            else
            {
                chunk = new List<T>();
                int last = _pos + ChunkSize;
                for (int i = _pos; i < count && i < last; i++, _pos++)
                {
                    chunk.Add(_data[_pos]);
                }
                return true;
            }
        }

        #endregion
    }
}

用法:

// create ChunkReader based on DataTable
var chunker = new ServiceCore.Helpers.ChunkReader<DataRow>(ds.Tables[0].Select().ToList(), 5); // 5 - size of chunk

List<DataRow> chunk;
while (chunker.Read(out chunk))
{
    // do somethind with chunk of data rows
}

答案 3 :(得分:0)

使用LINQ,您可以通过以下方式实现它,

    int rowCountPerTable = 5; //Number of tables would be based on this
    int currPos = 0;
    DataTable dt = ds.Tables[0];
    DataTable tempDt = dt.Clone();
    dt.Rows.OfType<DataRow>().ToList().ForEach(x =>
    {
        currPos++;
        tempDt.ImportRow(x);
        if (currPos == rowCountPerTable)
        {
            currPos = 0;
            tempDt.TableName = "Table" + (ds.Tables.Count + 1);
            ds.Tables.Add(tempDt);
            tempDt = dt.Clone();
        }
        else if ((dt.Rows.Count - 1) == dt.Rows.IndexOf(x))
        {
            tempDt.TableName = "Table" + (ds.Tables.Count + 1);
            ds.Tables.Add(tempDt);
        }
    });

希望这会有所帮助......