Linq嵌套属性

时间:2014-05-12 17:21:33

标签: c# linq

我有这个嵌套for循环,我想通过修改原始查询来消除:

foreach (var record in records)
{    
  foreach (var ap in record.approverList)
  {
    var approval = (from c in dataContext.approvals
                    where c.recordId == record.recordId
                    && c.personId == ap.personId
                    orderby c.modified descending
                    select c).FirstOrDefault();

    if (approval != null)
    {
      ap.vote = approval.vote;
    }

  }

}

修改

理想情况下,我想修改记录的原始查询,如下所示:

var records = (
  from record in dataContext.Records
  where record.statusId == RecordStatus.Submitted
).Include(e => e.approverList.Select(d => d.approver))
.ToList()

2 个答案:

答案 0 :(得分:1)

因此,真正的问题是您正在为每条记录中的每个批准执行查询。你不想这样做。您要做的是将您在数据库端的记录与您的批准相结合,以创建对的查询。只需一个简单的let即可选择所有联合批准中的一个匹配批准。

一旦您从与其配对的记录中查询了所有批准和批准列表,更新每个项目就足够了。

var query = from record in records
            from recordApproval in record.approverList
            join approval in approvals
            on new { record.recordId, recordApproval.personId } equals
            new { approval.recordId, approval.personId }
            into approvalMatches
            where approvalMatches.Any()
            let approval = approvalMatches.OrderByDescending(a => a.modified)
                .FirstOrDefault()
            select new
            {
                recordApproval,
                approval,
            };

foreach (var result in query)
    result.recordApproval.vote = result.approval.vote;

此外值得注意的是,您不应将records表示为结果集;你应该将它保存为非物质化查询,以便连接可以在数据库网站上进行。

答案 1 :(得分:0)

查看代码所需的逻辑似乎是:

对于每条记录的每个批准人,请获得他们的最新投票。

实现这一目标的最清晰方式(可读/可维护),并且只对数据库进行一次调用,看起来像这样:

注意:approvals.recordId应该是record.recordId的外键,或者代码稍微复杂一些(需要显式连接)

// get all the latest votes for submitted records
var votes = dataContext.approvals
    .Where(x => x.record.statusId == RecordStatus.Submitted)
    .OrderByDescending(x => x.modified) // only the latest vote counts, per person
    .GroupBy(x => new { x.recordID, x.personID })
    .Select(x => x.First())
    .ToList();

之后,您可以像这样使用列表:

// this lists all the distinct records
var recordIds = votes.Select(x => x.recordId).Distinct();

// see the votes for each record
foreach(var recordId in recordIds)
{
     var thisRecordsVotes = votes.Where(x => x.recordId = recordID).ToList();
}