我在SQL中有这个查询:
SELECT *
FROM TableName
WHERE myData IN (SELECT MAX(myData) AS DATA_MAX
FROM TableName
GROUP BY id1, id2)
我想在Linq(c#)中复制它 - 我该怎么做?
答案 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个记录