Linq:在做投影时设置一个属性

时间:2017-12-15 16:09:02

标签: c# linq

我正在做一个简单的GroupBy获取First元素,但我想修改每个结果的一个属性。

class M
{
 public string Name {get; set;}
 public int NOfPeopleWithTheSameName {get; set;}
 public string P1 {get; set;}
 public string P2 {get; set;}
 public string P3 {get; set;}
 public string P4 {get; set;}
 public string P5 {get; set;}
}  


List<M> myList = GetMyList();


var l2 = myList
   .GroupBy(m => m.Name)
   .Select(group => new M { Name = group.Key, NOfPeopleWithTheSameName = group.Count() });

这很简单,但如果类有很多属性(因为每个属性值都应该复制到新属性),这种方式不是最好的方法吗?我应该逐个复制它们。

我想简单地取元素并更改属性NOfPeopleWithTheSameName

2 个答案:

答案 0 :(得分:2)

您不需要创建新的M,您可以返回现有的var l2 = myList .GroupBy(m => m.Name) .Select(group => { var m = group.First(); m.NOfPeopleWithTheSameName = group.Count(); return m; }); ,例如:

public class ModelCount<T>
{
    public T Model { get; set; }
    public int Count { get; set; }
}

但是,如果你打算为你的模型添加一个属性,我建议改为使用另一个包装初始模型和计数的类 - 不要污染你的模型。例如,您可以使用这样的通用包装类:

var l2 = myList
   .GroupBy(m => m.Name)
   .Select(group => new ModelCount<M> 
   {
        Model = group.First(),
        Count = group.Count()
   });

现在这样组:

@Component({
  selector: 'app-transmission-history'
})
export class TransmissionHistoryComponent implements OnInit {

  @Input() theRecord: Record = null;

  constructor(private _transmissionHistoryService: TransmissionHistoryService) { }
}

答案 1 :(得分:1)

是的,你可以 ......

class Test 
{
    public string Name { get; set; }
    public int Number { get; set; }
}

var tests = new List<Test> { /* ... your data here ... */ };

var modifiedTests = tests.Select(test => { test.Name = "MODIFIED"; return test; });

// this actually executes above query and modifies your original items in the list:
var modifiedMaterialized = modifiedTests.ToList();

但你真的,真的(!)不应该!

LinQ是语言集成查询。有副作用的查询是邪恶的。胡子扭曲邪恶。不管怎样,你会为自己省下很多痛苦。

我认为你想要的不仅仅是LinQ,而是常规循环:

class M
{
 public string Name {get; set;}
 public int NOfPeopleWithTheSameName {get; set;}
 public string P1 {get; set;}
 public string P2 {get; set;}
 public string P3 {get; set;}
 public string P4 {get; set;}
 public string P5 {get; set;}
}  

List<M> myList = GetMyList();

var groups = myList.GroupBy(m => m.Name).ToList();

foreach(var group in groups)
{
    foreach(var member in group)
    {
        member.NOfPeopleWithTheSameName = group.Count();
    }
}