Entity framework core EF Core:获取与筛选器匹配的实体,但仅获取那些通过组合键在其分组中具有最新datetime属性的实体

Entity framework core EF Core:获取与筛选器匹配的实体,但仅获取那些通过组合键在其分组中具有最新datetime属性的实体,entity-framework-core,Entity Framework Core,我有一个定价类实体表 以前,Pricing表有一个基于3个外键的唯一索引:InstitutionId、SubmissionTypeId和FeeTypeId 现在,对于同一索引,它需要有多个可能的Pricing行,但我应该只使用DateTime列ActiveFrom的最新值,也就是说,对于给定的复合索引,我应该只使用最新的活动Pricing 我的存储库方法需要返回与两个外键值(InstitutionId和SubmissionTypeId)匹配的所有当前活动的Pricings) 我试着这样做: Da

我有一个
定价
类实体表

以前,
Pricing
表有一个基于3个外键的唯一索引:
InstitutionId
SubmissionTypeId
FeeTypeId

现在,对于同一索引,它需要有多个可能的
Pricing
行,但我应该只使用DateTime列
ActiveFrom
的最新值,也就是说,对于给定的复合索引,我应该只使用最新的活动
Pricing

我的存储库方法需要返回与两个外键值(
InstitutionId
SubmissionTypeId
)匹配的所有当前活动的
Pricings

我试着这样做:

DateTime today = DateTime.Today;
IQueryable<Pricing> filteredActivePricings = Context.Pricings
    .Where(pricing =>
        pricing.InstitutionId == institutionId
        && pricing.SubmissionTypeId == submissionTypeId
        && pricing.ActiveFrom <= today
    )
    .GroupBy(pricing => new { pricing.InstitutionId, pricing.SubmissionTypeId, pricing.FeeTypeId })
    .Select(pricingGroup => pricingGroup
        .OrderByDescending(pricing => pricing.ActiveFrom)
        .First()
    );
IList<Pricing> result = await filteredActivePricings.ToListAsync();
DateTime today=DateTime.today;
IQueryable filteredActivePricings=Context.Pricings
.其中(定价=>
pricing.InstitutionId==InstitutionId
&&pricing.SubmissionTypeId==SubmissionTypeId
&&pricing.ActiveFrom new{pricing.InstitutionId,pricing.SubmissionTypeId,pricing.FeeTypeId})
.选择(pricingGroup=>pricingGroup
.OrderByDescending(pricing=>pricing.ActiveFrom)
.First()
);
IList result=await filteredativepricings.toListSync();
但EF Core表示,它无法将该语法转换为有效的SQL查询


我已经找到了一个使用纯SQL代码的解决方案,但我希望使用EF Core的LINQ方法语法,因为我的代码库的其余部分都是用它编写的。

因此,我找到了我的问题和解决方案

问题是,正如@ivan stoev所指出的,我错误地认为
I分组
(IQueryable.GroupBy)包含一个
T
实体的集合,这些实体按键
K
分组,我必须以某种方式处理该集合以获得我的单个实体
T

下面是我的解决方案,它正确地利用了
IQueryable.GroupBy
方法,获取键值和日期的集合,然后在
Join
中使用这些键值和日期返回到表中,以获取我需要的实体的完整数据

DateTime today = DateTime.Today;
IQueryable<ActivePricingKey> filteredActivePricingKeyQuery = Context.Pricings
    .Where(pricing =>
        pricing.InstitutionId == institutionId
        && pricing.SubmissionTypeId == submissionTypeId
        && pricing.ActiveFrom <= today
    )
    .GroupBy<Pricing, PricingKey, ActivePricingKey>(
        (Pricing pricing) 
            => new PricingKey 
            { 
                InstitutionId = pricing.InstitutionId, 
                SubmissionTypeId = pricing.SubmissionTypeId, 
                FeeTypeId = pricing.FeeTypeId 
            },
        (PricingKey key, IEnumerable<Pricing> pricings) 
            => new ActivePricingKey 
            {
                InstitutionId = key.InstitutionId,
                SubmissionTypeId = key.SubmissionTypeId,
                FeeTypeId = key.FeeTypeId, 
                ActiveFrom = pricings.Max(pricing => pricing.ActiveFrom) 
            }
    );

IQueryable<Pricing> filteredActivePricingQuery = filteredActivePricingKeyQuery
    .Join(
        Context.Pricings,
        (ActivePricingKey activePricingKey)
            => new
            {
                activePricingKey.InstitutionId,
                activePricingKey.SubmissionTypeId,
                activePricingKey.FeeTypeId,
                activePricingKey.ActiveFrom
            },
        (Pricing pricing)
            => new
            {
                pricing.InstitutionId,
                pricing.SubmissionTypeId,
                pricing.FeeTypeId,
                pricing.ActiveFrom
            },
        (ActivePricingKey activePricingKey, Pricing pricing) => pricing
    );

ICollection<Pricing> pricings = await filteredActivePricingQuery.ToListAsync();
DateTime today=DateTime.today;
IQueryable FilteredActivityPricingKeyQuery=Context.Pricings
.其中(定价=>
pricing.InstitutionId==InstitutionId
&&pricing.SubmissionTypeId==SubmissionTypeId
&&来自新PricingKey的pricing.active
{ 
InstitutionId=pricing.InstitutionId,
SubmissionTypeId=pricing.SubmissionTypeId,
FeeTypeId=定价。FeeTypeId
},
(PricingKey,IEnumerable pricings)
=>新的ActivePricingKey
{
InstitutionId=key.InstitutionId,
SubmissionTypeId=key.SubmissionTypeId,
FeeTypeId=key.FeeTypeId,
ActiveFrom=pricings.Max(pricing=>pricing.ActiveFrom)
}
);
IQueryable filteredActivePricingQuery=filteredActivePricingKeyQuery
.加入(
上下文,Pricings,
(ActivePricingKey ActivePricingKey)
=>新的
{
activePricingKey.InstitutionId,
activePricingKey.SubmissionTypeId,
activePricingKey.FeeTypeId,
activePricingKey.ActiveFrom
},
(定价)
=>新的
{
pricing.InstitutionId,
pricing.SubmissionTypeId,
pricing.FeeTypeId,
pricing.ActiveFrom
},
(ActivePricingKey ActivePricingKey,定价)=>定价
);
ICollection pricings=await filteredActivePricingQuery.ToListSync();

所以,我找到了我的问题和解决方案

问题是,正如@ivan stoev所指出的,我错误地认为
I分组
(IQueryable.GroupBy)包含一个
T
实体的集合,这些实体按键
K
分组,我必须以某种方式处理该集合以获得我的单个实体
T

下面是我的解决方案,它正确地利用了
IQueryable.GroupBy
方法,获取键值和日期的集合,然后在
Join
中使用这些键值和日期返回到表中,以获取我需要的实体的完整数据

DateTime today = DateTime.Today;
IQueryable<ActivePricingKey> filteredActivePricingKeyQuery = Context.Pricings
    .Where(pricing =>
        pricing.InstitutionId == institutionId
        && pricing.SubmissionTypeId == submissionTypeId
        && pricing.ActiveFrom <= today
    )
    .GroupBy<Pricing, PricingKey, ActivePricingKey>(
        (Pricing pricing) 
            => new PricingKey 
            { 
                InstitutionId = pricing.InstitutionId, 
                SubmissionTypeId = pricing.SubmissionTypeId, 
                FeeTypeId = pricing.FeeTypeId 
            },
        (PricingKey key, IEnumerable<Pricing> pricings) 
            => new ActivePricingKey 
            {
                InstitutionId = key.InstitutionId,
                SubmissionTypeId = key.SubmissionTypeId,
                FeeTypeId = key.FeeTypeId, 
                ActiveFrom = pricings.Max(pricing => pricing.ActiveFrom) 
            }
    );

IQueryable<Pricing> filteredActivePricingQuery = filteredActivePricingKeyQuery
    .Join(
        Context.Pricings,
        (ActivePricingKey activePricingKey)
            => new
            {
                activePricingKey.InstitutionId,
                activePricingKey.SubmissionTypeId,
                activePricingKey.FeeTypeId,
                activePricingKey.ActiveFrom
            },
        (Pricing pricing)
            => new
            {
                pricing.InstitutionId,
                pricing.SubmissionTypeId,
                pricing.FeeTypeId,
                pricing.ActiveFrom
            },
        (ActivePricingKey activePricingKey, Pricing pricing) => pricing
    );

ICollection<Pricing> pricings = await filteredActivePricingQuery.ToListAsync();
DateTime today=DateTime.today;
IQueryable FilteredActivityPricingKeyQuery=Context.Pricings
.其中(定价=>
pricing.InstitutionId==InstitutionId
&&pricing.SubmissionTypeId==SubmissionTypeId
&&来自新PricingKey的pricing.active
{ 
InstitutionId=pricing.InstitutionId,
SubmissionTypeId=pricing.SubmissionTypeId,
FeeTypeId=定价。FeeTypeId
},
(PricingKey,IEnumerable pricings)
=>新的ActivePricingKey
{
InstitutionId=key.InstitutionId,
SubmissionTypeId=key.SubmissionTypeId,
FeeTypeId=key.FeeTypeId,
ActiveFrom=pricings.Max(pricing=>pricing.ActiveFrom)
}
);
IQueryable filteredActivePricingQuery=filteredActivePricingKeyQuery
.加入(
上下文,Pricings,
(ActivePricingKey ActivePricingKey)
=>新的
{
activePricingKey.InstitutionId,
activePricingKey.SubmissionTypeId,
activePricingKey.FeeTypeId,
activePricingKey.ActiveFrom
},
(定价)
=>新的
{
pricing.InstitutionId,
pricing.SubmissionTypeId,
pricing.FeeTypeId,
pricing.ActiveFrom
},
(ActivePricingKey ActivePricingKey,定价)=>定价
);
ICollection pricings=等待过滤器删除活动定价