如何修改下面的查询以包含行号列(即:基于一个结果的索引)?
var myResult = from currRow in someTable
where currRow.someCategory == someCategoryValue
orderby currRow.createdDate descending
select currRow;
EDIT1:我正在寻找{idx, col1, col2...col-n}
而不是{idx, row}
的结果。
EDIT2:行号应对应于结果行而不是表行。
EDIT3:我DataBind
这些结果为GridView
。我的目标是在GridView
添加行号列。也许一种不同的方法会更好。
答案 0 :(得分:30)
使用方法 - 语法,其中Enumerable.Select
与索引重载:
var myResult = someTable.Select((r, i) => new { Row = r, Index = i })
.Where(x => x.Row.someCategory == someCategoryValue)
.OrderByDescending(x => x.Row.createdDate);
请注意,此方法假定您需要表中行的原始索引而不是筛选结果,因为我在使用Where
进行筛选之前选择了索引。
编辑:我正在寻找{idx,col1,col2 ... col-n}的结果 {idx,row}。行号应该对应于结果行 表格行。
然后选择包含所需列的匿名类型:
var myResult = someTable.Where(r => r.someCategory == someCategoryValue)
.OrderByDescending(r => r.createdDate)
.Select((r, i) => new { idx = i, col1 = r.col1, col2 = r.col2, ...col-n = r.ColN });
答案 1 :(得分:6)
使用此Select
方法:
通过合并元素的索引,将序列的每个元素投影到新的表单中。
示例:
var myResult = someTable.Where(currRow => currRow.someCategory == someCategoryValue)
.OrderByDescending(currRow => currRow.createdDate)
.Select((currRow, index) => new {Row = currRow, Index = index + 1});
回复您的修改:
如果您想要DataTable
作为结果,只需使用DataView
即可以非Linq方式使用,然后再添加一列。
someTable.DefaultView.RowFilter = String.Format("someCategory = '{0}'", someCategoryValue);
someTable.DefaultView.Sort = "createdDate";
var resultTable = someTable.DefaultView.ToTable();
resultTable.Columns.Add("Number", typeof(int));
int i = 0;
foreach (DataRow row in resultTable.Rows)
row["Number"] = ++i;
答案 2 :(得分:3)
只是为了好玩,这里有Select
的替代方案,有两个参数:
var resultsWithIndexes = myResult.Zip(Enumerable.Range(1, int.MaxValue - 1),
(o, i) => new { Index = i, Result = o });
答案 3 :(得分:2)
怎么样?
int i;
var myResult = from currRow in someTable
where currRow.someCategory == someCategoryValue
orderby currRow.createdDate descending
select new {Record = i++, currRow};
答案 4 :(得分:2)
根据你的编辑1. 不,你不能 Linq按原样返回表格。您可以构建每个列,但是会丢失映射实体的功能。
以前曾多次询问过这个问题:How do you add an index field to Linq results
答案 5 :(得分:1)
如果想要保持列的平面列表(即OP的编辑2)并且还想要一个适用于任何IEnumerable的通用解决方案而不要求您列出预期列的集合,则没有直接的方法。 / p>
然而,有一种迂回的方式可以解决它,即使用here中的ToDataTable()方法将查询结果转储到DataTable中,然后将RowNumber列添加到该表中。
var table = query.ToList().ToDataTable();
table.Columns.Add("RowNum", typeof(int));
int i = 0;
foreach (DataRow row in table.Rows)
row["RowNum"] = ++i;
这可能会导致大型数据集的性能问题,但它也不会非常缓慢。在我的机器上,一个约6500行的数据集需要33ms来处理。
如果您的原始查询返回了匿名类型,那么该类型定义将在转换中丢失,因此当您调用table.AsEnumerable()时,您将失去对生成的IEnumerable的列名称的静态类型。换句话说,不是能够编写类似table.AsEnumerable()。First()。RowNum而是必须编写table.AsEnumerable()。First()[" RowNum"]
但是,如果您不关心性能并且真的想要静态键入,那么您可以使用JSON.NET将DataTable转换为json字符串,然后返回基于匿名类型的列表。原始查询结果。此方法需要占位符RowNum字段存在于原始查询结果中。
var query = (from currRow in someTable
where currRow.someCategory == someCategoryValue
orderby currRow.createdDate descending
select new { currRow.someCategory, currRow.createdDate, RowNum = -1 }).ToList();
var table = query.ToDataTable();
//Placeholder RowNum column has to already exist in query results
//So not adding a new column, but merely populating it
int i = 0;
foreach (DataRow row in table.Rows)
row["RowNum"] = ++i;
string json = JsonConvert.SerializeObject(table);
var staticallyTypedList = JsonConvert.DeserializeAnonymousType(json, query);
Console.WriteLine(staticallyTypedList.First().RowNum);
这增加了我的6500项目数据集的处理时间约120毫秒。
这很疯狂,但确实有效。
答案 6 :(得分:0)
我知道我迟到了,但我想展示一下对我有用的东西。
我有一个对象列表,对象上有一个整数属性,用于"行号" ...或者在这种情况下,"序列号"。这就是我为填充该字段所做的工作:
myListOfObjects = myListOfObjects.Select((o, i) => { o.SequenceNumber = i; return o; }).ToList();
我很惊讶地发现这很有用。
答案 7 :(得分:0)
这对我来说很有帮助-Excel工作表提取。匿名类型
var UploadItemList = ItemMaster.Worksheet().AsEnumerable().Select((x, index) => new
{
Code = x["Code"].Value == null ? "" : x["Code"].Value.ToString().Trim(),
Description = x["Description"].Value == null ? "" : x["Description"].Value.ToString().Trim(),
Unit = x["Unit"].Value == null ? "" : x["Unit"].Value.ToString().Trim(),
Quantity = x["Quantity"].Value == null ? "" : x["Quantity"].Value.ToString().Trim(),
Rate = x["Rate"].Value == null ? "" : x["Rate"].Value.ToString().Trim(),
Amount = x["Amount"].Value == null ? "" : x["Amount"].Value.ToString().Trim(),
RowNumber = index+1
}).ToList();
答案 8 :(得分:0)
int Lc = 1;
var Lst = LstItemGrid.GroupBy(item => item.CategoryName)
.Select(group => new { CategoryName = group.Key, Items = group.ToList() ,RowIndex= Lc++ })
.ToList();