简体   繁体   English

使用Entity Framework Core从数据库记录的最大和最小

[英]Max and min record from database using Entity Framework Core

I have a simple method that return rage of data from db according to some parameters, and it is simple: 我有一个简单的方法,可以根据一些参数从db返回大量数据,这很简单:

public async Task<IEnumerable<P2PStats>> GetFilteredNetStats(ushort id, ushort remoteId, DateTime start, DateTime end)
{
    using (var ctx = new DataContext())
    {
        IQueryable<P2PStats> query = ctx.P2PStats
             .Where(stat => stat.Id == id && stat.Date >= start && stat.Date <= end)
             .Where(stat => stat.P2PStatsDetailed.Any(detail => detail.RemoteId == remoteId))
             .Select(stat => new P2PStats
             {
                 Id = stat.Id,
                 AxmCardId = stat.Id,
                 Date = stat.Date,
                 P2PStatsDetailed = stat.P2PStatsDetailed.Where(detail => detail.RemoteId == remoteId).ToList()
             });

        return await query.ToListAsync();
    }
}

It returns collection of P2PStats(well actually a task but in final result a collection). 它返回P2PStats的集合(实际上是一个任务,但最终结果是一个集合)。 Can this be modified so that I can get only 2 values from database first with lowest date second with highest? 可以对此进行修改,以便我只能从数据库中获得两个值最低的日期,第二个具有最高的日期吗?

I tried Max and Min but only after the query has been materialized and I end up with max and min value or property not whole record. 我尝试了最大和最小,但仅在查询实现后才出现,最终得到的是最大和最小值或属性,而不是整个记录。

This problem can be solved by the removal of filtering by Id and the addition of the method .Max() and .Min() to your code. 此问题可以通过删除ID过滤以及在代码中添加方法.Max().Min()来解决。

Below is an example of how this would look: 以下是此示例的示例:

 public async Task<IEnumerable<P2PStats>> GetNetStatsLowestAndHighestDate(ushort id, ushort remoteId, DateTime start, DateTime end)
{
    using (var ctx = new DataContext())
    {
        IQueryable<P2PStats> query = ctx.P2PStats
             .Where(stat => stat.Date >= start && stat.Date <= end)
             .Where(stat => stat.P2PStatsDetailed.Any(detail => detail.RemoteId == remoteId))
             .DefaultIfEmpty(0)
             .Max(s => s.Date)

             .Select(stat => new P2PStats
                                        {
                                            Id = stat.Id,
                                            AxmCardId = stat.Id,
                                            Date = stat.Date,
                                            P2PStatsDetailed = stat.P2PStatsDetailed.Where(detail => detail.RemoteId == remoteId).ToList()
                                        });

        IQueryable<P2PStats> query2 = ctx.P2PStats
             .Where(stat => stat.Date >= start && stat.Date <= end)
             .Where(stat => stat.P2PStatsDetailed.Any(detail => 
        detail.RemoteId == 
        remoteId))
             .DefaultIfEmpty(0)
             .Min(s => s.Date)

             .Select(stat => new P2PStats
                                        {
                                            Id = stat.Id,
                                            AxmCardId = stat.Id,
                                            Date = stat.Date,
                                            P2PStatsDetailed = 
        stat.P2PStatsDetailed.Where(detail => detail.RemoteId == remoteId).ToList()
                                        });

        var results = query1.Concat(query2);

        return await results.ToListAsync();

    }
}

i assume you have records for the same ID. 我假设您有相同ID的记录。 just created a linqpad example (i was not sure if you want list of min value, max value rows or just min and max) the approach would be to group on same field (propably on ID) and pick min, max 刚刚创建了一个linqpad示例(我不确定您是否要列出最小值,最大值行或仅列出min和max),方法是将同一字段分组(适当地在ID上)并选择min,max

void Main()
{
    test t = new test();
    var l = new List<test>() {
        new test() {ID = 0, a1="aaa", a2 = 10},
        new test() {ID = 1, a1="aaa", a2 = 40},
        new test() {ID = 2, a1="aaa", a2 = 70},
        new test() {ID = 3, a1="aaa", a2 = 50},
        };

    l.Dump("original");
    l.GroupBy(g => g.a1).Select(s => new { max = s.Max(mm => mm.a2), min = s.Min(mi => mi.a2) }).Dump("return 2 values");

    List<test> lRes = new List<test>();
    lRes.Add(l.OrderBy(o => o.a2).First());
    lRes.Add(l.OrderBy(o => o.a2).Last());
    lRes.Dump("return table of min record and max record");


}

public class test
{
    public int ID { get; set; }
    public string a1 { get; set; }
    public int a2 { get; set; }
    public test() { }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM