LINQ选择Max为一列而Disting为另一列的行

pse*_*der 2 c# linq vb.net linq-to-entities

我正在使用LINQ to Entities来查询以下MS-SQL表:

RateID  RateTypeID  Amount  EffectiveDate   IsRetired
------  ----------  ------  -------------   ---------
1       1           0.565   1/1/2013 0:00   FALSE
2       2           6.000   1/1/2013 0:00   FALSE
3       3           9.000   1/1/2013 0:00   FALSE
4       4           12.000  1/1/2013 0:00   FALSE
5       5           1.500   1/1/2013 0:00   FALSE
6       1           0.550   7/1/2012 0:00   FALSE
7       1           0.495   1/1/2012 0:00   FALSE
8       3           8.000   1/1/2011 0:00   FALSE
9       3           11.000  1/1/2015 0:00   FALSE
10      5           2.000   7/1/2013 0:00   TRUE
Run Code Online (Sandbox Code Playgroud)

我想构建一个函数,它将使用LINQ返回一个IQueryable(Of Rate)我可以加入其他查询的函数,以便有效地确定应用于每个项目的当前速率RateTypeID. IsRetired必须是假的,我需要最近的一行EffectiveDate.

这是我得到的最接近的(LINQPad VB语句):

Dim dateNow As Date = Date.Now
Dim result = (
    From r In Rates
    Where r.IsRetired = False And r.EffectiveDate <= dateNow
    Group r By r.RateTypeID
    Into rg = Group
    Select New With {
        .cr = rg.OrderByDescending(Function(r) r.EffectiveDate).Take(1)
    }
)
result.Dump()
Run Code Online (Sandbox Code Playgroud)

此查询返回DbQuery(Of AnonymousType_1(Of IEnumerable(Of Rate)))(每个具有1个费率项的集合的集合),这不是我想要的.

这个Q&A解决了一个非常类似的问题,但是在SQL而不是LINQ中: 我如何用SQL中的另一列选择MAX(列值),DISTINCT的行?

我在vb.net编码,但也会采取ac#answer.谢谢!

Adu*_*cci 6

在返回时使用Take()return ,所以:IEnumerable<T>FirstOrDefault()<T>

IQueryable<RecentRate> query = from r in Rates
                               where r.IsRetired == false && r.EffectiveDate <= dateNow
                               group r by r.RateTypeID into rg
                               select new RecentRate
                               {
                                 Rate = rg.OrderByDescending(r => r.EffectiveDate).FirstOrDefault()
                               };
Run Code Online (Sandbox Code Playgroud)

这可能有效:

   IQueryable<Rate> query = from r in Rates
                            where r.IsRetired == false && r.EffectiveDate <= dateNow
                            group r by r.RateTypeID into rg
                            select rg.OrderByDescending(r => r.EffectiveDate).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

我认为这是VB语法

Dim result = (
    From r In Rates
    Where r.IsRetired = False And r.EffectiveDate <= dateNow
    Group r By r.RateTypeID
    Into rg = Group
    Select rg.OrderByDescending(Function(r) r.EffectiveDate).FirstOrDefault()
)
Run Code Online (Sandbox Code Playgroud)