Linq to sql Linq to Sql:选择不同的行,同时忽略指定的列

Linq to sql Linq to Sql:选择不同的行,同时忽略指定的列,linq-to-sql,group-by,distinct,Linq To Sql,Group By,Distinct,如果我有如下查询/结果集 from t1 in table1 join t2 in table2 on t1.ID equals t2.ID join t3 in table3 on t2.ID equals t3.ID select new MyClass() { ID = t1.ID, Name = t2.Name, Rank = t2.Rank, City = t3.City } ID | Name | City | Rank 01 | Test | Fake |

如果我有如下查询/结果集

from t1 in table1
join t2 in table2 on t1.ID equals t2.ID
join t3 in table3 on t2.ID equals t3.ID
select new MyClass()
{
   ID = t1.ID,
   Name = t2.Name,
   Rank = t2.Rank,
   City = t3.City
}

ID | Name | City | Rank
01 | Test | Fake | 876
01 | Test | Fake | 755
02 | Blah | Fake | 765
执行.Distinct()将返回所有3条记录,但如果我想要第一条和第三条记录,并且不想从结果集中删除任何列,该怎么办?有没有一种方法可以在执行distinct时指定要忽略的列,或者显式地包含在distinct中,以便我可以执行类似的操作

// pseudo code
.Distinct(o => o.Name.FirstOrDefault())

我认为使用GROUPBY可以做到这一点,但这似乎是缓慢而混乱的,特别是如果我需要对多个列进行分组以避免排除太多行的话。有什么想法吗?谢谢。

不,您不能指定投影来确定
Distinct
的相等性。(我有一些扩展方法可以为LINQ to对象实现这一点,但这是另一回事。)

我建议您使用
GroupBy
,可能与
First
结合使用:

var query = from t1 in table1
            join t2 in table2 on t1.ID equals t2.ID
            join t3 in table3 on t2.ID equals t3.ID
            select new { t1.ID, t2.Name, t2.Rank, t3.City } into tuple
            group tuple by new { tuple.ID, tuple.Name, tuple.City } into grouping
            let first = grouping.First() // For convenience
            select new MyClass
            {
                ID = first.ID, City = first.City,
                Name = first.Name, Rank = first.Rank
            };
请注意,此操作的结果可能不是确定性的-您将取每组的第一项,忽略排名-因此您可能会得到排名876的记录,或者您可能会得到示例中排名755的记录

我不知道这在SQL中会是什么样子,但您应该通过日志记录进行检查,然后运行查询探查器来查看成本