选择每个IGrouping中的第一个,聚合一些属性,而无需显式分配每个未聚合的属性

时间:2018-09-18 14:11:38

标签: c# linq linq-to-sql

有没有一种方法可以在聚合某些属性的同时选择每个IGrouping的第一个元素,而无需在投影中显式分配每个未聚合的属性?

例如,SelectAggregatedFirstsOfMyThings()在做我想要的事情。但是,在我的实际情况中,MyThing具有30个属性。我想保留每个IGrouping中第一个的属性值,而不必为每个非聚合属性明确声明MyIntA = x.First().MyIntA。是否有其他一些速记语法来实现此目的(无需引入类似Automapper的东西)?

public class MyThing {

    public int MyFkId { get; set; }
    public int MyIntA { get; set; }
    public int MyIntB { get; set; }
    public DateTime MyDate {get; set; }
    ...
}

public class MyCaller {
    public IQueryable<MyThing> SelectAggregatedFirstsOfMyThings(IOrderedQueryable<MyThing> myThings) =>
        myThings.GroupBy(t => t.MyFkId)
                .Select(g => new MyThing
                {
                    MyIntA = g.First().MyIntA,
                    MyIntB = g.First().MyIntB,
                    MyDate = g.Max(d => d.MyDate)
                    ...
                }
}

1 个答案:

答案 0 :(得分:1)

您可以使用语句lambda创建一个新的MyThing,该First()是从该组的AsEnumerable初始化的,然后重新分配聚合的属性以创建所需的对象。由于您使用的是LINQ to SQL,因此必须在语句lambda之前使用public IQueryable<MyThing> SelectAggregatedFirstsOfMyThings(IOrderedQueryable<MyThing> myThings) => myThings.GroupBy(t => t.MyFkId) .AsEnumerable() .Select(g => { var r = new MyThing(g.First()); r.MyDate = g.Max(d => d.MyDate); // assign remaining aggregated properties ... return r; }); 将查询结果拉(实例化)到客户端。

    $url = $this->api_url . "/folders";
    $headers = [
        'Authorization' => 'Bearer ' . $this->access_token,        
    ];
    $client = new Client();
    $response = $client->post($url, [
        'headers' => $headers, 
        'form_params' => [
            'name' => $name,
            'parent' => [
                'id' => $parent_id
            ]
        ]
    ]);