2017-10-13 71 views
0

我有這樣的模式: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在過去一直在迅速發展。 –

回答

1

我會考慮嘗試避免在您的域實體中解析計算的屬性,而是在查詢數據以填充視圖模型時查找這些屬性。

如果您的視圖模型需要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()並深入到子字段中。

1

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");