SQL "IN" 语句在linq 查询错误,如何解决?

SQL "IN" statement in linq query mistake, how resolve?

我在 SQL 中有这个查询:

SELECT * 
FROM TableName
WHERE myData IN (SELECT MAX(myData) AS DATA_MAX  
                 FROM TableName 
                 GROUP BY id1, id2) 

我想在 Linq (c#) 中复制它 - 我该怎么做?

这并不是一个直接的答案,因为它不是通过 LINQ 实现的;但它确实解决了问题,并且用最少的麻烦:

您可以使用 "Dapper" 等工具来执行原始查询,而无需涉及任何 LINQ。如果您使用 LINQ-to-SQL 或 Entity Framework 之类的东西,那里的数据上下文 通常有一个原始查询 API你可以使用,但我要展示一个 "Dapper" 实现:

class SomeType
{
    // not shown: properties that look like the columns
    // of [TableName] in the database - correct names/types
}
...
var data = connection.Query<SomeType>(@"
SELECT * FROM TableName
WHERE myData IN (Select max(myData) as DATA_MAX  from TableName group
by id1, id2)").AsList();

这种方法使得迁移现有 SQL 查询变得非常容易 而无需 将所有内容重写为 LINQ。

如果您使用的是 LINQ-to-SQL,DataContext 有一个类似的 ExecuteQuery<TResult> method. Entity Framework has a SqlQuery 方法

你可以试试这个。也许它会起作用。

var myData = (from c in _context.TableName
    group c by new
    {
        c.id1,
        c.id2
    } into gcs
    select new
    {
       gcs.Max(p=>p.myData)
    }).AsQueryable();

var result = (from t in _context.TableName
              where myData.Contains(t.myData)
              select t).ToList();

长话短说 - 不要使用 LINQ,优化查询并使用像 Dapper 这样的 microORM 将结果映射到 类:

var query = "Select * "
            "from ( select *, " +
            "       ROW_NUMBER() OVER (partition by id1,id2 order by mydata desc) AS RN " +
            "       From TableName ) T " +
            "where RN=1";
var data = connection.Query<SomeType>(query);

LINQ 不能替代 SQL。 ORM 一般不适合编写这样的报告查询。

报告查询需要大量优化,通常必须在生产中进行更改。您不想 每次查询更改时都必须重新部署您的应用程序。在这种情况下,far 最好创建一个视图并使用像 Dapper 这样的 microOMR 映射到它。

此特定查询可能需要 两次 table 次扫描,一次计算每个 id1,id2 的最大值,一次查找匹配 [=15] 的行=].中间数据也必须假脱机到 tempdb 中。如果 mydata 被索引覆盖,它可能不是一个如此昂贵的查询。如果不是,所有数据将被扫描两次。

另一种方法是根据id1、id2,通过mydata计算每一行的排名。您可以使用 ROW_NUMBER、RANK、NTILE 等排名函数之一来执行此操作。

Select * 
from ( select *,
              ROW_NUMBER() OVER (partition by id1,id2 order by mydata desc) AS RN
       From TableName) T 
where RN=1

您可以直接将查询与 Dapper 一起使用,或者创建一个视图并将您的实体映射到视图,而不是 table 本身。

一种选择是创建一个 MyTableRanked 视图 :

CREATE VIEW MyTableRanked AS
select *,
       ROW_NUMBER() OVER (partition by id1,id2 order by mydata desc) AS RN
From TableName

这将允许您编写:

var query="Select * from MyTableRanked where RN=@rank";
var data = connection.Query<SomeType>(query,new {rank=2});

允许您return每个 ID1、ID2 组合的前 N ​​条记录