Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何对记录进行分组并仅检索前N个记录的第一个组_C#_Entity Framework_Linq_Entity Framework Core_Ef Core 2.0 - Fatal编程技术网

C# 如何对记录进行分组并仅检索前N个记录的第一个组

C# 如何对记录进行分组并仅检索前N个记录的第一个组,c#,entity-framework,linq,entity-framework-core,ef-core-2.0,C#,Entity Framework,Linq,Entity Framework Core,Ef Core 2.0,我有以下记录 ID BatchID ClientName CreatedDateTime ----------- -------------- --------------- ----------------------- 1 NULL B 2018-02-16 19:07:46.320 2 NULL B 2018-02-1

我有以下记录

ID          BatchID     ClientName           CreatedDateTime
----------- -------------- --------------- -----------------------
1           NULL           B             2018-02-16 19:07:46.320
2           NULL           B             2018-02-16 19:07:46.320
3           NULL           B             2018-02-16 19:07:46.597
4           NULL           B             2018-02-16 19:07:46.597
5           NULL           B             2018-02-16 19:10:10.260
6           NULL           B             2018-02-16 19:10:10.260
7           NULL           B             2018-02-16 19:21:34.303
8           NULL           B             2018-02-16 19:21:34.303
9           NULL           B             2018-02-16 19:21:44.780
10          NULL           B             2018-02-16 19:21:44.780
11          NULL           A             2018-02-16 19:24:35.623
12          NULL           A             2018-02-16 19:24:35.623
13          NULL           A             2018-02-16 19:24:42.867
14          NULL           A             2018-02-16 19:24:42.867
我在efcore中使用linqtosql

我想过滤
BatchID
NULL
的记录,然后按
CreatedDateTime
对过滤后的记录进行排序,然后按
ClientName
对它们进行分组,然后从第一个组中选取前5个记录

基于上面给定的记录集,它应该返回ClientName
B
id为1,2,3,4,5的记录

这是我的问题

 var result = await _DBContext.BatchRequests
                .Where(x => x.BatchID.HasValue == false)
                .OrderBy(x => x.CreatedDateTime)
                .GroupBy(x => x.ClientName)
                .FirstAsync();
问题
1> 查询返回客户端
A

2> 我如何只录制前5张唱片

更新1

Sql事件探查器显示以下内容,它甚至不在Sql中分组

SELECT [x].[ID], [x].[BatchID], [x].[ClientName], [x].[CreatedDateTime]
FROM [BatchRequests] AS [x]
WHERE CASE
    WHEN [x].[BatchID] IS NULL
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END <> 0
ORDER BY [x].[ClientName]
选择[x].[ID],[x].[BatchID],[x].[ClientName],[x].[CreatedDateTime]
从[BatchRequests]到[x]
在哪里
当[x].[BatchID]为空时
然后强制转换(1为位)否则强制转换(0为位)
结束0
订购人[x]。[ClientName]

您必须以如下方式投影组结果:

result = await _DBContext.BatchRequests
            .Where(x => x.BatchID.HasValue == false)
            .OrderBy(x => x.CreatedDateTime)
            .ThenBy(x => x.ClientName)
            .GroupBy(x => x.ClientName)
            .Select( x => new { ClientName= x.ClientName,
                                 TopFive = x.Take(5)
                         })
            .FirstAsync();

首先,在将LINQ查询转换为SQL的
Queryable
实现中,如果后跟
GroupBy
,则通常
OrderBy
无效(被忽略)

其次,EF Core目前不将
GroupBy
查询转换为SQL,而是在内存中处理它们(所谓的),这使得它们的效率非常低。考虑到这一点,您最好将工作分为两个查询—一个用于获取第一组的
ClientName
,另一个用于获取所需的结果:

var baseQuery = _DBContext.BatchRequests
    .Where(x => x.BatchId == null)
    .OrderBy(x => x.CreatedDateTime);

var clientName = await baseQuery
    .Select(x => x.ClientName)
    .FirstOrDefaultAsync();

var result = await baseQuery
    .Where(x => x.ClientName == clientName)
    .Take(5)
    .ToListAsync();
实际上,您可以将这两个查询组合起来,但我不确定这是否会更有效(可能更糟):


您的
OrderBy
GroupBy
之后没有多大意义-您必须对组进行排序。那么,您希望如何对组进行排序?(同样,一个简单的
x.BatchID==null
可能会产生更好的SQL。)仅供参考,EF Core与LINQ to SQL或EF6没有任何共同之处。例如,正如您已经注意到的,它当前没有将
GroupBy
查询转换为SQL。检索内存中的所有记录并在内存中进行分组并只取前N有什么用。您将不得不等待EF Core 2.1。这是我认为EF Core还没有准备好投入生产的一个原因。它产生相同的结果并返回client
B
。事实上,SQL探查器显示的SQL与我在上面更新1中发布的查询的SQL完全相同。您确定这是生成的SQL吗?是的,正如有人指出的,当您使用group by时,order by不会产生任何影响
var baseQuery = _DBContext.BatchRequests
    .Where(x => x.BatchId == null)
    .OrderBy(x => x.CreatedDateTime);

var result = await baseQuery
    .Where(x => x.ClientName == baseQuery.Select(y => y.ClientName).FirstOrDefault())
    .Take(5)
    .ToListAsync();