【问题标题】:Translate SQL query into Entity Framework Core 2.1将 SQL 查询转换为 Entity Framework Core 2.1
【发布时间】:2020-02-19 01:11:28
【问题描述】:

我对 Entity Framework Core v2.1 有点陌生,我的问题如下。

就我而言,有一个名为ServiceCarrier 的表,如下所示:

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

通过使用这个 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));  

结果:

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

我想将其转换为 Entity Framework Core 2.1。

提前感谢您的帮助。

【问题讨论】:

    标签: c# sql entity-framework-core .net-core-2.1


    【解决方案1】:

    您自己的解决方案还可以,但问题是这种情况

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

    其中carriers 是内存收集导致client evaluation,因此虽然它会产生正确的结果,但性能不会很好。

    更好的方法是准备一个 id 集合并使用 Contains 方法,这是在 EF(核心)中实现 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();
    

    生成的 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]
    )
    

    【讨论】:

      【解决方案2】:

      我能够为上述问题提供解决方案。我的解决方案如下所示。如果有人找到更好的解决方案而不是这个解决方案,请分享。

      _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();
      

      【讨论】:

      • @SelvaTS 对我来说是的。你看到这个有什么错误吗?运营商列表应该被传递到sql
      猜你喜欢
      • 2020-07-18
      • 2021-11-08
      • 1970-01-01
      • 2021-05-08
      • 2017-10-23
      • 2018-12-29
      • 1970-01-01
      • 2021-05-09
      • 2021-10-14
      相关资源
      最近更新 更多