拥有以下模型(为了简单起见,我发布了接口)。
public class LengthViewModel
{
public int Length { get; set; }
public string Category { get; set; }
}
public class SlopeViewModel
{
public int Slope { get; set; }
public string Category { get; set; }
}
public class RatingViewModel
{
public double Rating { get; set; }
public string Category { get; set; }
}
然后我在另一个ViewModel中有一个每个类型的ObservableCollection。
public ObservableCollection<LengthViewModel> Lengths { get; set; }
public ObservableCollection<SlopeViewModel> Slopes { get; set; }
public ObservableCollection<RatingViewModel> Ratings { get; set; }
我需要将上面的列表转换为一个列表,下面是它应该创建的新列表类型。
public ObservableCollection<LengthSlopeRatingViewModel> Aggregate { get; set; }
public class LengthSlopeRatingViewModel
{
public string Category { get; set; }
public int Length { get; set; }
public int Slope { get; set; }
public double Rating { get; set;}
}
到目前为止我尝试了但似乎仍然坚持如何选择每个转换列表的属性。
var lengths = Lengths.Select(p => new LengthSlopeRatingViewModel
{
Category = p.Category,
Length = p.Length
});
var slopes = Slopes.Select(p => new LengthSlopeRatingViewModel
{
Category = p.Category,
Slope = p.Slope
});
var ratings = Ratings.Select(p => new LengthSlopeRatingViewModel
{
Category = p.Category,
Rating = p.Rating
});
// Concat and group them, then select new type again with the properties?
CourseRatings = lengths.Concat(slopes)
.Concat(ratings)
.GroupBy(p => p.Category)
.Select(g => g.ToList())
.As<IEnumerable<LengthSlopeRatingViewModel>>()
.ToObservableCollection();
示例,如果您有一个长度,斜率和等级的实例Category = "Black"
和另一个带Category = "Blue"
的实例,我应该得到两个LengthSlopeRatingViewModel实例,一个带Category = "Black"
的实例和相应的值第一场比赛和一场Category = "Blue"
。
答案 0 :(得分:2)
可以使用join s。
按照通用条件组合多个列表如果您只想在所有馆藏一个相应类别项目时获得LengthSlopeRatingViewModel
结果:
Aggregate = new ObservableCollection<LengthSlopeRatingViewModel>(
from l in Lengths
join s in Slopes on l.Category equals s.Category
join r in Ratings on s.Category equals r.Category
select new LengthSlopeRatingViewModel {
Category = l.Category,
Length = l.Length,
Slope = s.Slope,
Rating = r.Rating
});
如果是某些评分缺少,您仍然需要一个默认评级列表:
Aggregate = new ObservableCollection<LengthSlopeRatingViewModel>(
from l in Lengths
join s in Slopes on l.Category equals s.Category
join r in Ratings on s.Category equals r.Category into ratings
from r in ratings.DefaultIfEmpty()
select new LengthSlopeRatingViewModel {
Category = l.Category,
Length = l.Length,
Slope = s.Slope,
Rating = r?.Rating ?? 0
});
前者相当于:
Aggregate = new ObservableCollection<LengthSlopeRatingViewModel>(
Lengths
.Join(Slopes, _ => _.Category, _ => _.Category,
(l, s) => new LengthSlopeRatingViewModel
{ Category = l.Category, Length = l.Length, Slope = s.Slope })
.Join(Ratings, _ => _.Category, _ => _.Category,
(ls, r) => { ls.Rating = r.Rating; return ls; }));
这些应该很容易适应其他用例,例如:缺少斜率(添加DefaultIfEmpty
)或缺少长度(更改连接顺序),除非您想要一个真正的完全外部连接,即期望任何长度,斜率和评级不包含另一个集合中的类别。然后创建所有类别的列表,并在左外连接视图模型:
var categories =
Lengths.Select(_ => _.Category).Concat(
Slopes.Select(_ => _.Category)).Concat(
Ratings.Select(_ => _.Category))
.Distinct();
Aggregate = new ObservableCollection<LengthSlopeRatingViewModel>(
from c in categories
join l in Lengths on c equals l.Category into lengths
from l in lengths.DefaultIfEmpty()
join s in Slopes on c equals s.Category into slopes
from s in slopes.DefaultIfEmpty()
join r in Ratings on c equals r.Category into ratings
from r in ratings.DefaultIfEmpty()
select new LengthSlopeRatingViewModel
{
Category = c,
Length = l?.Length ?? 0, // or any other default
Slope = s?.Slope ?? 0,
Rating = r?.Rating ?? 0
});