如何使用Linq Select投影修复实体框架核心“参数类型不匹配”

时间:2019-05-09 14:16:06

标签: c# linq asp.net-core .net-core entity-framework-core

当尝试使用Entity Framework Core和Linq进行直接投影时,出现“参数类型不匹配”异常。

我已经调查了可能的原因,并将其范围缩小到导致错误的Select(请参见下文)。有GitHub issue用简单的类型和可选的导航实体描述了类似的情况,但是没有建议的解决方案对我有用。它不是nullable类型,我尝试在任何子属性上强制转换或使用Value。我还尝试过在DbContext中将关系设置为required,这并不是很理想。

这是存储库中的Linq查询:

return await _dashboardContext.PresetDashboardConfig
    .Where(config => config.DashboardTypeId == dashboardType && config.OrganisationType = organisationType)
    .GroupBy(config => config.GroupId)
    .Select(config => new DashboardConfigDTO
    {
        DashboardType = config.First().DashboardTypeId,
        OrganisationId = organisationId,
        WidgetGroups = config.Select(group => new WidgetGroupDTO
        {
            Id = group.Id,
            Name = group.GroupName,
            TabOrder = group.TabOrder,

            // Problem Select below:
            Widgets = group.Widgets.Select(widget => new WidgetConfigDTO
            {
                IndicatorId = widget.IndicatorId,
                ScopeId = widget.ScopeId.ToString(),
                ParentScopeId = widget.ParentScopeId.ToString(),
                WidgetType = widget.WidgetType,
                WidgetSize = widget.WidgetSize,
                Order = widget.Order
            })
        })
    })
    .SingleOrDefaultAsync();

实体:

public class DashboardConfig
{
    public int Id { get; set; }
    public int DashboardTypeId { get; set; }
    public int OrganisationType {get; set; }
    public int GroupId { get; set; }
    public string GroupName { get; set; }
    public int TabOrder { get; set; }
}

public class PresetDashboardConfig : DashboardConfig
{
    public ICollection<PresetWidgetConfig> Widgets { get; set; }
}

public class WidgetConfig
{
    public int Id { get; set; }
    public int IndicatorId { get; set; }
    public long ScopeId { get; set; }
    public long? ParentScopeId { get; set; }
    public int WidgetType { get; set; }
    public int WidgetSize { get; set; }
    public int Order { get; set; }
}

public class PresetWidgetConfig : WidgetConfig
{
    public int PresetDashboardConfigId { get; set; }
}

最后是DbContext ModelBuilder:

modelBuilder.Entity<PresetDashboardConfig>(entity =>
{
    entity.Property(e => e.GroupName)
        .HasMaxLength(32)
        .IsUnicode(false);

    entity.HasMany(e => e.Widgets)
        .WithOne();
});

以下是根据Henk的评论的DTO类:

public class DashboardConfigDTO
{
    public int DashboardType { get; set; }
    public int OrganisationId { get; set; }
    public IEnumerable<WidgetGroupDTO> WidgetGroups { get; set; }
}

public class WidgetGroupDTO
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int TabOrder { get; set; }
    public IEnumerable<WidgetConfigDTO> Widgets { get; set; }
}

public class WidgetConfigDTO
{
    public int IndicatorId { get; set; }
    public string ScopeId { get; set; }
    public string ParentScopeId { get; set; }
    public int WidgetType { get; set; }
    public int WidgetSize { get; set; }
    public int Order { get; set; }
}

0 个答案:

没有答案