我从使用PHP w/MySQL转到ASP .NET Core。
问题:
为了方便说明,假设有以下两个表:T: {ID, Description, FK}
和States:{ID, ID_T, Time, State}
。它们之间存在1:n的关系(ID_T
引用T.ID
)。
我需要获取T
中所有FK
特定值的记录(假设为1
),以及相关的最新记录在States
中(如果有)。
在SQL中可以这样写:
SELECT T.ID, T.Description, COALESCE(s.State, 0) AS 'State' FROM T
LEFT JOIN (
SELECT ID_T, MAX(Time) AS 'Time'
FROM States
GROUP BY ID_T
) AS sub ON T.ID = sub.ID_T
LEFT JOIN States AS s ON T.ID = s.ID_T AND sub.Time = s.Time
WHERE FK = 1
我正在努力编写一个在LINQ(或流畅API)中有效等效的查询。到目前为止,我得到的最佳工作解决方案是:
from t in _context.T
where t.FK == 1
join s in _context.States on t.ID equals o.ID_T into _s
from s in _s.DefaultIfEmpty()
let x = new
{
id = t.ID,
time = s == null ? null : (DateTime?)s.Time,
state = s == null ? false : s.State
}
group x by x.id into x
select x.OrderByDescending(g => g.time).First();
当我执行查询时,在输出窗口中检查得到的 SQL 查询内容如下:
SELECT [t].[ID], [t].[Description], [t].[FK], [s].[ID], [s].[ID_T], [s].[Time], [s].[State]
FROM [T] AS [t]
LEFT JOIN [States] AS [s] ON [T].[ID] = [s].[ID_T]
WHERE [t].[FK] = 1
ORDER BY [t].[ID]
不仅选择了比我需要的更多的列(在实际方案中有更多列)。查询中没有分组,所以我想它会从数据库中选择所有内容(而且 States 将会非常庞大),分组/过滤是在数据库外部进行的。
问题:
你会怎么做?
有没有 LINQ / Fluent API 中的高效查询?
如果没有,可以使用哪些解决方法?
原始 SQL 破坏了抽象出特定数据库技术的概念,并且在当前的 Entity Framework Core 中使用起来非常笨重(但也许这是最好的解决方案)。
对我来说,这看起来是使用数据库视图的一个很好的例子 - 再次强调,Entity Framework Core 并不真正支持它(但也许这是最好的解决方案)。