我有IEnumerable<RuleSelection>
这些属性:
public class RuleSelection{
public int RuleId { get; set;}
public int? CriteriaId { get; set; }
public int? CriteriaSourceId{ get; set; }
}
<{1}}中的{p> RuleId
并非唯一。
我是否可以编写一个linq查询来将这些规范标准化为RuleSelection
,这将是:
IEnumerable<Rule>
public class Rule{
public int RuleId { get; set; }
public IEnumerable<int> Criteria { get; set; }
public IEnumerable<int> CriteriaSource { get; set; }
}
将是唯一的,属性Rule.RuleId
和Criteria
将包含{{1}的所有CriteriaSource
和CriteriaId
分别。
答案 0 :(得分:10)
听起来你想要这样的东西:
var rules = selections.GroupBy(rs => rs.RuleId)
.Select(g => new Rule {
RuleId = g.Key,
Criteria = g.Select(rs => rs.CriteriaId)
.Where(c => c != null)
.Select(c => c.Value)
.ToList(),
CriteriaSource = g.Select(rs => rs.CriteriaSourceId)
.Where(c => c != null)
.Select(c => c.Value)
.ToList(),
});
答案 1 :(得分:0)
使用我的FullOuterGroupJoin扩展方法
你可以:theRules.FullOuterGroupJoin(theRules,
r => r.RuleId,
r => r.RuleId,
(crit, critSource, id) => new Rule {
RuleId = id,
Criteria = crit
.Where(r => r.CriteriaId.HasValue)
.Select(r => r.CriteriaId.Value),
CriteriaSource = critSource
.Where(r => r.CriteriaSourceId.HasValue)
.Select(r => r.CriteriaSourceId.Value),
}
);
答案 2 :(得分:0)
写这个:
var rules =
from sel in selections
group sel by sel.RuleId into rg
select new Rule {
RuleId = rg.Key,
Criteria = rg.Select(r => r.CriteriaId).FilterValues(),
CriteriaSource = rg.Select(r => r.CriteriaSourceId).FilterValues(),
};
我创建了以下FilterValues
扩展名(以消除重复):
public static IEnumerable<T> FilterValues<T>(
this IEnumerable<T?> items)
where T : struct
{
// omitting argument validation
return
from item in items
where item.HasValue
select item.Value;
}
我打算提供一个纯粹的查询语法版本的JonSkeet的答案。我放弃了这一点,努力消除财产分配的重复,并结束了这个组合扩展&amp;查询语法方法。