2013-03-24 55 views
0

我有一个ID和名称的列表,我想填充其他两个列表的属性。LINQ:填写列表<ViewModel>与来自2个不同模型的属性

List<Foo> foolist = foo.fromdatasource(); // for all items in this list 
List<Bar> = barlist from bar.datasource(); // fill a new list with Name property from this list 

List<ViewModel> viewModel = new List<ViewModel>(); 

foreach (Foo foo in foolist) 
{ 
    viewmodel.Add(new ViewModel 
    { 
     Id = foo.Id 
     Name = barlist.Where(f => f.Id == b.Id).Select(s => s.Name) 
    }); 
} 

最后一行没有给出从barlist中的项目对应于来自愚人主义的ID的名称。有谁知道这样做的正确方法?

+0

'。选择(S => s.Name)'会返回一个匿名对象的集合'名称'属性。你想使用伯爵Les解决方案。在附注中,请阅读“访问修改后的关闭”(我假设你的意思是'f.Id == foo.Id')。 – alexn 2013-03-24 17:51:44

+0

@alexn:你确定它会返回anon的集合。具有'Name'属性的对象?我认为它应该返回一个'String'集合,或者'Name'类型。 – 2013-03-24 18:05:07

+0

@BorisB。你当然是对的,我的不好:) – alexn 2013-03-24 18:24:45

回答

2

低于线替换你的最后一行:

Name = barlist.First(f => f.Id == b.Id).Name; 

更多约束,以避免null例外,你可以写:

var viewModels = foo.Select(f => { 
    var bar = barlist.FirstOrDefault(b => f.Id == b.Id); 

    return new ViewModel() { 
     Id = f.Id, 
     Name = bar == null? null : bar.Name 
    }; 
}); 

您也可以使用该方法SingleOrDefault而不是FirstOrDefault,它的相同的结果,因为我猜你的Id是唯一的

+1

这将是'FirstOrDefault'和'SingleOrDefault'之间的性能差异,因为第二个迭代通过整个集合,每当FirstOrDefault'只要它返回元素找到。 – MarcinJuraszek 2013-03-24 17:59:48

+0

@MarcinJuraszek:这是好点 – 2013-03-24 18:01:26

+1

嗨Cuong,你的第一个建议的确给了我“序列中没有匹配的元素”,但你的第二个答案的确有诀窍。谢谢! – stefjnl 2013-03-24 18:16:14

1

什么是bb.ID

如果是的东西,你要使用它,然后

Name = barlist.FirstOrDefault(f => f.Id == foo.Id).Name; 

否则

Name = barlist.FirstOrDefault(f => f.Id == b.Id).Name; 
相关问题