Linq join从第二个表中获取最新值

时间:2018-02-21 08:59:44

标签: .net linq

我有两个表,让它成为A和B. A是主表,B是次表。我需要的是当我从B加入A和B的最新行以获得相应的A值并通过使用linq按B的主键排序时     表A.     A_id值     1 a1     2 b1

Table B
B_Id   values    A_id
1    123        1
2    456        1
3    789        2
4    321        2

Result should be 

A_id  name B_Id
2   b1     4
1   a1     2

我当前的代码仅以相反的顺序返回。我知道代码有一些语法错误,请不要考虑它

from a in db.A
join b in db.b on a.A_Id equals b.B_Id into tem 
from b in tem.Take(1) orderby chat.Ch_IdNo descending

2 个答案:

答案 0 :(得分:2)

我更喜欢使用Max而不是OrderByDescending / First,但我不确定哪个性能更高,哪个最适合SQL或EF。

因此,您可以将TableA连接到TableB,然后从连接组中找到最大(最新?)B_Id并返回。

var ans = from a in TableA
          join b in TableB on a.A_id equals b.A_id into bj
          let maxB_Id = bj.Max(b => b.B_Id)
          select new { a, b = bj.First(b => b.B_Id == maxB_Id) };

在lambda语法中:

var ansl = TableA.GroupJoin(TableB, a => a.A_id, b => b.A_id, (a, bj) => new { a, b = bj.First(b => b.B_Id == bj.Max(b2 => b2.B_Id)) });

注意:这会重新计算Max的每个成员的bj,而let会使用隐藏的select来传递值。您可以修改lambda以使用完整的主体来避免这种情况:

var ansl = TableA.GroupJoin(TableB, a => a.A_id, b => b.A_id, (a, bj) => {
                                var maxB_Id = bj.Max(b2 => b2.B_Id);
                                return new { a, b = bj.First(b => b.B_Id == maxB_Id) };
                            });

如果你对OrderByDescending没问题,你也可以使用群组加入:

var ans2 = from a in TableA
           join b in TableB on a.A_id equals b.A_id into bj
           select new { a, b = bj.OrderByDescending(b => b.B_Id).First() };

在lambda语法中:

var ans2l = TableA.GroupJoin(TableB, a => a.A_id, b => b.A_id, (a, bj) => new { a, b = bj.OrderByDescending(b => b.B_Id).First() });

答案 1 :(得分:1)

虽然你没有定义它,但我想用短语“B中对应A值的最新行”,你的意思是如果你把B中的所有行都用于某个A_id,那么最新的一行就是B_Id的最高值。在您的示例中:A_Id 1为B_Id 2的行,A_Id为2为B_Id 4的行。

让我们分两步完成:首先我得到每个A_id最新的表B项,然后我用表A加入它们:

var latestTableB = tableB
    .GroupBy(b => b.A_id)
    .Select(group => group.OrderByDescending(groupElement => groupElement.B_Id)
     .First();

单词:将表B的所有元素分组为具有相同A_id的组。然后通过降序B_Id对组中的所有元素进行排序。结果的第一个元素是具有最新B_Id

的元素

将其加入表A的元素:

var result = latestTableB.Join(tableA,
   tableBElement => tableBElement.A_Id,
   tableAElement => tableAElement.A_Id,
   (b, a) => new
   {
        A_Id = b.A_Id,
        name = a.Value,
        B_Id = b.B_Id,
   });

单词:将latestTableB中的元素与tableA中的元素连接起来。从latestTableB中的每个元素取A_Id;从表A中的每个元素取A_Id。当他们macth时,使用匹配的b和来自latestTableB和tableA的a来创建一个具有所需属性的新对象

TODO:将这两个语句连接成一个