在linq查询错误的SQL“IN”语句中,如何解决?

时间:2018-02-08 09:22:36

标签: c# sql linq sql-to-linq-conversion

我在SQL中有这个查询:

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

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

3 个答案:

答案 0 :(得分:2)

这不是一个直接的答案,因为它没有通过LINQ实现它;但它确实解决了问题,只需要少量的烦恼:

您可以使用"Dapper"之类的工具执行原始查询,而不涉及任何LINQ。如果您正在使用LINQ-to-SQL或Entity Framework之类的东西,那么数据上下文通常还有一个可以使用的原始查询API,但我将展示一个“Dapper” “实施:

<fo:inline>I</fo:inline><!--
--><fo:inline>I</fo:inline>

这种方法可以很容易地迁移现有的SQL查询,而不必将所有内容重写为LINQ。

如果您使用的是LINQ-to-SQL,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(); 有一个类似的ExecuteQuery<TResult>方法。实体框架具有SqlQuery方法

答案 1 :(得分:0)

你可以试试这个。可能会有用。

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

答案 2 :(得分:0)

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

\S+(\|\d+\|\S+\.)

LINQ不是SQL的替代品。一般来说,ORM不是要写这样的报告查询。

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

此特定查询可能需要两个表扫描,一个用于计算每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); 的最大值,另一个用于查找匹配id1,id2的行。中间数据也必须假脱机到tempdb中。如果索引涵盖mydata,则可能不是如此昂贵的查询。如果不是,则所有数据将被扫描两次。

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

mydata

您可以直接使用Dapper查询或创建视图并将实体映射到视图,而不是表本身。

一种选择是创建Select * from ( select *, ROW_NUMBER() OVER (partition by id1,id2 order by mydata desc) AS RN From TableName) T where RN=1 视图:

MyTableRanked

这将允许你写:

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

允许您返回每个ID1,ID2组合的前N个记录