如何从 C# Expression Func 获取列值

问题描述 投票:0回答:1

我的 EF 模型如下所示:

public partial class SalesPipelineEntryClosedInformation : FoxHireEntityBase
{
    [Key]
    public int Id { get; set; }
    public string ClosedDetails { get; set; }
    public bool Won { get; set; }
    public int? TypeCompetitorId { get; set; }
    public int? TypeLostReasonId { get; set; }
    public int? TypeDeclineReasonId { get; set; }

    [ForeignKey(nameof(TypeCompetitorId))]
    [InverseProperty(nameof(TypeCompetitor.SalesPipelineEntryClosedInformations))]
    public virtual TypeCompetitor Competitor { get => Get(_competitor); set => _competitor = value; }
    
    [ForeignKey(nameof(TypeLostReasonId))]
    [InverseProperty(nameof(TypeLostReason.SalesPipelineEntryClosedInformations))]
    public virtual TypeLostReason LostReason { get => Get(_lostReason); set => _lostReason = value; }

    [ForeignKey(nameof(TypeDeclineReasonId))]
    [InverseProperty(nameof(TypeDeclineReason.SalesPipelineEntryClosedInformations))]
    public virtual TypeDeclineReason DeclineReason { get => Get(_declineReason); set => _declineReason = value; }
}

我有一个方法可以根据实体属性的更改来更新统计信息。看起来像这样:

private async Task CalculateStats(InsightType insightType)
{
    if (insightType.Value == InsightType.Competitor.Value)
    {
        await processStatsList(x => x.TypeCompetitorId.HasValue, x => x.Competitor.Name, new List<string> {"Competitor"}, InsightType.Competitor);
    }
    else if (insightType.Value == InsightType.IndustryReason)
    {
        await processStatsList(x => x.TypeDeclineReasonId.HasValue, x => x.DeclineReason.Name, new List<string> {"DeclineReason"}, InsightType.IndustryReason);
    }
    else if (insightType.Value == InsightType.LostReason)
    {
        await processStatsList(x => x.TypeLostReasonId.HasValue, x => x.LostReason.Name, new List<string> {"LostReason"}, InsightType.LostReason);
    }
}

processStatsList
方法是:

private async Task processStatsList(Expression<Func<SalesPipelineEntryClosedInformation, bool>> whereClause, 
                                    Expression<Func<SalesPipelineEntryClosedInformation, string>> relatedTableNameValue, 
                                    List<string> includes, InsightType insightType)
{
    await clearRecordTypes(insightType.Value);
    var closedInfo = await _genericRepository.GetList(whereClause, includes);

    var stats = closedInfo.Select(x => new
        {
            x.TypePipelineDealTypeId,
            relatedTableNameValue.Value
        }).GroupBy(x => new {x.Name})
        .Select(x => new SalesInsightStat
        {
            Count = x.Count(),
            Name = x.Key.Name,
            InsightTypeId = insightType.Value
        }).ToList();

    await _genericRepository.AddRangeAsync(stats);
} 

我不确定如何设置第二个表达式

relatedTableNameValue
来输出“名称”列的实际值。所有三个表都有相同的名称列,所以我只是想获取该列的值。显然,
relatedTableNameValue.Value
不起作用,但我不知道如何获得该值。

c# lambda func
1个回答
0
投票

由于

closedInfo
IEnumerable
,您可以编译表达式并调用它:

var stats = closedInfo
    .Select(x => new
    {
        x.TypePipelineDealTypeId,
        relatedTableNameValue.Compile()(x)
    })
    .GroupBy(x => new {x.Name})

但是由于

relatedTableNameValue
不与
IQueryable
一起使用,我建议将参数更改为
Func
:

private async Task processStatsList(Expression<Func<SalesPipelineEntryClosedInformation, bool>> whereClause,
    Func<SalesPipelineEntryClosedInformation, string> relatedTableNameValue,
     List<string> includes, 
     InsightType insightType)
{
    // ...
    var stats = closedInfo
        .Select(x => new
        {
            x.TypePipelineDealTypeId,
            relatedTableNameValue(x)
        })
        .GroupBy(x => new {x.Name})

    // ...
}
© www.soinside.com 2019 - 2024. All rights reserved.