我有一个这样的linq查询:
var accounts =
from account in context.Accounts
from guranteer in account.Gurantors
where guranteer.GuarantorRegistryId == guranteerRegistryId
select new AccountsReport
{
recordIndex = ?
CreditRegistryId = account.CreditRegistryId,
AccountNumber = account.AccountNo,
}
我想用 LINQ 返回的集合中当前行号的值填充 recordIndex。如何获取行号?
linq-to-entity 不支持行号。必须首先从数据库中检索不带行号的记录,然后通过 linq-to-对象添加行号。像这样:
var accounts =
(from account in context.Accounts
from guranteer in account.Gurantors
where guranteer.GuarantorRegistryId == guranteerRegistryId
select new
{
CreditRegistryId = account.CreditRegistryId,
AccountNumber = account.AccountNo,
})
.AsEnumerable() // Moving to linq-to-objects
.Select((r, i) => new AccountReport
{
RecordIndex = i,
CreditRegistryId = r.CreditRegistryId,
AccountNumber = r.AccountNo,
});
LINQ to Objects 对任何枚举器都内置了这个:
http://weblogs.asp.net/fmarguerie/archive/2008/11/10/using-the-select-linq-query-operator-with-indexes.aspx
编辑:虽然IQueryable也支持它(在这里和这里),但已经提到,不幸的是,这不适用于LINQ to SQL/Entities。
new []{"aap", "noot", "mies"}
.Select( (element, index) => new { element, index });
将导致:
{ { element = aap, index = 0 },
{ element = noot, index = 1 },
{ element = mies, index = 2 } }
还有其他具有额外索引参数重载的 LINQ 扩展方法(如 .Where
尝试像这样使用 let:
int[] ints = new[] { 1, 2, 3, 4, 5 };
int counter = 0;
var result = from i in ints
where i % 2 == 0
let number = ++counter
select new { I = i, Number = number };
foreach (var r in result)
{
Console.WriteLine(r.Number + ": " + r.I);
}
我现在无法使用实际的LINQ to SQL或实体框架对其进行测试。请注意,上面的代码将在查询的多次执行之间保留计数器的值。
如果您的特定提供程序不支持此功能,则始终可以 foreach(从而强制执行查询)并在代码中手动分配编号。
因为问题内部的查询按单个 id 过滤,所以我认为给出的答案不会有所帮助。当然,您可以在内存客户端完成所有操作,但根据数据集的大小以及是否涉及网络,这可能是一个问题。
如果您需要等效的 SQL ROW_NUMBER [..] OVER [..]
,我知道的唯一方法是在 SQL 服务器中创建一个视图并针对该视图进行查询。
经过测试并有效:
按如下方式修改代码:
int counter = 0;
var accounts =
from account in context.Accounts
from guranteer in account.Gurantors
where guranteer.GuarantorRegistryId == guranteerRegistryId
select new AccountsReport
{
recordIndex = counter++
CreditRegistryId = account.CreditRegistryId,
AccountNumber = account.AccountNo,
}
希望这有帮助..虽然晚了:)