EF Linq 获取表中行的最新版本

Mik*_*ike 0 c# linq entity-framework

我有一个表,其中包含有关项目和版本的详细信息,如下所示:

+--------+-----------+------------+----------------------------+
| BookId | VersionId | InstanceId |         TitleText          |
+--------+-----------+------------+----------------------------+
|      1 |         1 |          1 | A great book!              |
|      1 |         2 |          2 | Great Book, v2!            |
|      2 |         1 |          3 | Cooking for Dummies        |
|      3 |         1 |          4 | Networks for Dummies       |
|      2 |         2 |          5 | Cooking for Smarter People |
+--------+-----------+------------+----------------------------+
Run Code Online (Sandbox Code Playgroud)

我正在尝试查询 BookId 的最新(最高) VersionId 的所有行。所以我想要的结果集如下所示:

+--------+-----------+------------+----------------------------+
| BookId | VersionId | InstanceId |         TitleText          |
+--------+-----------+------------+----------------------------+
|      1 |         2 |          2 | Great Book, v2!            |
|      3 |         1 |          4 | Networks for Dummies       |
|      2 |         2 |          5 | Cooking for Smarter People |
+--------+-----------+------------+----------------------------+
Run Code Online (Sandbox Code Playgroud)

我为得到这个而运行的 SQL 是:

select t1.* from Books t1
left outer join Books t2
on (t1.BookId = t2.BookId and t1.VersionId < t2.VersionId)
where t2.BookId is null
Run Code Online (Sandbox Code Playgroud)

但经过一番谷歌搜索后,我无法弄清楚如何将其转换为 linq 查询(使用扩展方法 sytax)。我看到的示例倾向于连接两个不同的表,我只是不知道如何将其塑造为我需要的。

找到了这个,它似乎与我正在寻找的很接近,但是如果 Foo 和 Bar 是同一张桌子,我该怎么办?

Foo.GroupJoin(
          Bar, 
          foo => foo.Foo_Id,
          bar => bar.Foo_Id,
          (x,y) => new { Foo = x, Bars = y })
    .SelectMany(
          x => x.Bars.DefaultIfEmpty(),
          (x,y) => new { Foo=x.Foo, Bar=y});
Run Code Online (Sandbox Code Playgroud)

lc.*_*lc. 5

一种方法是将您的反连接转换为不存在的位置:

select t1.*
from Books t1
where not exists (
    select 1
    from Books t2
    where t2.BookId = t1.BookId and t2.VersionId > t1.VersionId
)
Run Code Online (Sandbox Code Playgroud)

应该将 LINQ 翻译为:

AllBooks.Where(t1 => 
    !AllBooks.Any(t2 => t1.BookId == t2.BookId && t2.VersionId > t1.VersionId))
Run Code Online (Sandbox Code Playgroud)