简体   繁体   English

将 SQL 查询转换为 Entity Framework Core 2.1

[英]Translate SQL query into Entity Framework Core 2.1

I'm little bit new to Entity Framework Core v2.1, and my problem is as below.我对 Entity Framework Core v2.1 有点陌生,我的问题如下。

In my case there is a table called ServiceCarrier like this:就我而言,有一个名为ServiceCarrier的表,如下所示:

ServiceId CarrierId
-------------------
1         1  
2         1  
4         1  
1         2  
2         2  
5         2   
1         20028  
2         20028  
5         20028  

By using this SQL query, I was able to get the result set needed:通过使用此 SQL 查询,我能够获得所需的结果集:

SELECT serviceid  
FROM T  
GROUP BY serviceid  
WHERE carrierid IN (1, 20028)  
HAVING count(*) = (SELECT COUNT(DISTINCT carrierid)  
                   FROM T 
                   WHERE carrierid IN (1, 20028));  

Results:结果:

 ServiceId 
 ---------
 1  
 2  

And I want to convert it to Entity Framework Core 2.1.我想将其转换为 Entity Framework Core 2.1。

Appreciate your help in advance.提前感谢您的帮助。

I was able to make a solution for that above question.我能够为上述问题提出解决方案。 My solution is shown below.我的解决方案如下所示。 And if anyone found better solution rather than this solution please share.如果有人找到了更好的解决方案而不是这个解决方案,请分享。

_dbContext.ServiceCarriers
.Where(sc => carriers.Any(c => c.CarrierId == sc.CarrierId))
.GroupBy(scg => scg.Service)
.Where(sc1 => sc1.Count() == _dbContext.ServiceCarriers
                             .Where(scc => carriers.Any(c => 
                                          c.CarrierId == scc.CarrierId))
                             .Select(t => t.CarrierId)
                             .Distinct()
                             .Count()
).Select(sr => sr.Key)
 .ToList();

Your own solution is ok, but the problem is that condition like你自己的解决方案没问题,但问题是这样的情况

.Where(sc => carriers.Any(c => c.CarrierId == sc.CarrierId))

where carriers is in-memory collection leads to client evaluation , so while it will produce a correct result, the performance won't be good. carriers在内存中收集导致 客户端评估,因此虽然它会产生正确的结果,但性能不会很好。

A better way is to prepare a collection of ids and use Contains method, which is the typical way to implement the LINQ equivalent of SQL IN operator in EF (Core):更好的方法是准备一组 id 并使用Contains方法,这是在 EF(Core)中实现 SQL IN运算符的 LINQ 等效项的典型方法:

var carrierIds = carriers.Select(e => e.CarrierId);

var result = db.ServiceCarriers
    .Where(sc => carrierIds.Contains(sc.CarrierId))
    .GroupBy(sc => sc.ServiceId)
    .Where(scg => scg.Count() == db.ServiceCarriers
        .Where(sc => carrierIds.Contains(sc.CarrierId))
        .Select(sc => sc.CarrierId)
        .Distinct()
        .Count()
    )
    .Select(scg => scg.Key)
    .ToList();

The resulting SQL query is almost the same as the original:生成的 SQL 查询与原始查询几乎相同:

SELECT [sc].[ServiceId] AS [Key]
FROM [ServiceCarriers] AS [sc]
WHERE [sc].[CarrierId] IN (1, 20028)
GROUP BY [sc].[ServiceId]
HAVING COUNT(*) = (
    SELECT COUNT(*)
    FROM (
        SELECT DISTINCT [sc0].[CarrierId]
        FROM [ServiceCarriers] AS [sc0]
        WHERE [sc0].[CarrierId] IN (1, 20028)
    ) AS [t]
)

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

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