我有这个型号:
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并在List中获取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 :(得分: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");
答案 1 :(得分:1)
我考虑避免尝试解析域实体中的计算属性,而是在查询数据以填充视图模型时尝试解决这些问题。
如果您的视图模型需要TotalPrice和LastOperation,那么提供一个Repository或返回的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。 ?。语法可能不是必需的或不受支持的,因此可能只需要&#34;。&#34;。使用您渴望或延迟加载这些相关实体并从实体实例执行Linq的方法,请小心.SingleOrDefault()并向下钻取到子字段。