EF核心包括()没有查询到所有儿童的

问题描述:

我有这样的模式:EF核心包括()没有查询到所有儿童的

public class RepairRequest 
{ 
    [Key] 
    public int Id { get; set; } 
    public List<RepairAction> RepairActions { get; set; } 
    public decimal TotalPrice => RepairActions.Sum(r => r.ActionPrice); 
    public string LastOperation => RepairActions.LastOrDefault().RepairOperation.Description; 
} 

public class RepairAction 
{ 
    [Key] 
    public int Id { get; set; } 
    public int RepairRequestId { get; set; } 
    public RepairRequest RepairRequest { get; set; } 
    public int RepairOperationId { get; set; } 
    public RepairOperation RepairOperation { get; set; } 
    public decimal ActionPrice { get; set; } 
} 

public class RepairOperation 
{ 
    [Key] 
    public int Id { get; set; } 
    public string Description { get; set; } 
} 

我想查询RepairRequests并获得TotalPrice也LastOperation的清单,但对于这两个属性不起作用。这是我迄今为止所尝试的:

using (var context = new ServiceManagerContext(new DbContextOptions<ServiceManagerContext>())) { 
    var data = context.RepairRequests 
     .Include(r => r.RepairActions).ThenInclude(r => r.RepairOperation); // Only LastAction works 
     //.Include("RepairActions").Include("RepairActions.RepairOperation"); // Only LastAction works 
     //.Include(r => r.RepairActions); // Only TotalPrice works 
     //.Include("RepairActions"); // Only TotalPrice works 

    var repairRequest = data.FirstOrDefault(r => r.Id == 5); 
    Assert.NotNull(repairRequest); 
    Assert.Equal(60.0m, repairRequest.RepairPrice); 
    Assert.Equal("Παραδόθηκε", repairRequest.LastAction); 
} 

谢谢。

+0

'LastAction'或'LastOperation'?你将它们混淆 – GGO

+0

LastOperation。抱歉。 – dseferlis

+0

请始终明确指出您正在使用的是哪个版本。 ESP。 ef-core在过去一直在迅速发展。 –

我会考虑尝试避免在您的域实体中解析计算的属性,而是在查询数据以填充视图模型时查找这些属性。

如果您的视图模型需要TotalPrice和LastOperation,然后提供一个存储库或此类返回的IQueryable可以展开查询返回所需要的使用延迟执行,而不是试图依靠预先加载整个树:

即,

也就是说

IQueryable<RepairRequest> requests = context.RepairRequests.Where(x => x.Id == 5); // Or pull from a Repository returning the IQueryable 
var viewModelData = requests.Select(x => new {x.Id, TotalPrice = x.RepairActions.Sum(), LastOperation = x.RepairActions.LastOrDefault()?.RepairOperation?.Description }).SingleOrDefault(); 

这应该执行一个更优化的查询,并返回一个匿名类型只需要填入你想显示什么视图模型的数据。 iffy位是在没有修复操作的情况下,或者是没有操作的修复操作.EF应该避免null ref,并且只返回null。这个?语法可能不是必需或支持的,所以它可能只需要“。”。使用一种方法,你急于或懒惰地加载这些相关的实体并将Linq从实体实例中删除,注意.SingleOrDefault()并深入到子字段中。

Firstaball必须声明外键和标志虚拟财产,如:

public class RepairRequest 
{ 
    [Key] 
    public int Id { get; set; } 
    public virtual ICollection<RepairAction> RepairActions { get; set; } 
    public decimal TotalPrice => RepairActions.Sum(r => r.ActionPrice); 
    public string LastOperation => RepairActions.LastOrDefault().RepairOperation.Description; 
} 

public class RepairAction 
{ 
    [Key] 
    public int Id { get; set; } 
    public decimal ActionPrice { get; set; } 

    public int RepairRequestId { get; set; } 
    [ForeignKey("RepairRequestId ")] 
    public virtual RepairRequest RepairRequest { get; set; } 

    public int RepairOperationId { get; set; } 
    [ForeignKey("RepairOperationId")] 
    public RepairOperation RepairOperation { get; set; } 
} 

然后,你可以调用该方法,它加载所有的孩子值:

var data = context.RepairRequests.Include("RepairActions.RepairOperation");