【发布时间】:2021-09-02 06:50:03
【问题描述】:
我习惯了 EF 6,我是 EF Core 的新手。我正在尝试从与查找表有一些外键关系的表中进行简单的提取。
我从这个开始:
List<StatementModel> myStatements = new List<StatementModel>();
myStatements = db.Statements.Select(s => new StatementModel
{
StatmentId = s.StatementId,
EmployeeNumber = s.EmployeeNumber,
FirstName = s.Employee.FirstName,
LastName = s.Employee.LastName,
PlanType = s.Employee.PlanType != null ? s.Employee.PlanType.PlanTypeName : "",
FiscalPeriod = s.FiscalPeriod.StartDate.ToString("yyyy-MM-dd") + " - " + s.FiscalPeriod.EndDate.ToString("yyyy-MM-dd"),
CostCenterId = s.Employee.CostCenterId,
RVPName = s.Employee.CostCenter.Evp != null ? s.Employee.CostCenter.Evp.FirstName + " " + s.Employee.CostCenter.Evp.LastName : "",
SVPName = s.Employee.CostCenter.Svp != null ? s.Employee.CostCenter.Svp.FirstName + " " + s.Employee.CostCenter.Svp.LastName : "",
LOBMgrName = s.Employee.CostCenter.Lobmgr != null ? s.Employee.CostCenter.Lobmgr.FirstName + " " + s.Employee.CostCenter.Lobmgr.LastName : "",
AdminApprovalStatus = s.AdminApprovalStatus.ApprovalStatusName,
StatementStatus = s.StatementStatus.StatementStatusName,
AmountDue = s.AmountDue
}).Where(s => s.StatementStatusId == "PAA").ToList();
但它给了我一个运行时错误,说它无法将其转换为 SQL。我认为这是.ToString() 和日期格式的问题。
所以我改成:
List<StatementModel> myStatements = new List<StatementModel>();
var statements = db.Statements.Where(s => s.StatementStatusId == "PAA").ToList();
foreach (var s in statements)
{
StatementModel sm = new StatementModel();
sm.StatmentId = s.StatementId;
sm.EmployeeNumber = s.EmployeeNumber;
sm.FirstName = s.Employee.FirstName;
sm.LastName = s.Employee.LastName;
sm.PlanType = s.Employee.PlanType != null ? s.Employee.PlanType.PlanTypeName : "";
sm.FiscalPeriod = s.FiscalPeriod.StartDate.ToString("yyyy-MM-dd") + " - " + s.FiscalPeriod.EndDate.ToString("yyyy-MM-dd");
sm.CostCenterId = s.Employee.CostCenterId;
sm.RVPName = s.Employee.CostCenter.Evp != null ? s.Employee.CostCenter.Evp.FirstName + " " + s.Employee.CostCenter.Evp.LastName : "";
sm.SVPName = s.Employee.CostCenter.Svp != null ? s.Employee.CostCenter.Svp.FirstName + " " + s.Employee.CostCenter.Svp.LastName : "";
sm.LOBMgrName = s.Employee.CostCenter.Lobmgr != null ? s.Employee.CostCenter.Lobmgr.FirstName + " " + s.Employee.CostCenter.Lobmgr.LastName : "";
sm.AdminApprovalStatus = s.AdminApprovalStatus.ApprovalStatusName;
sm.StatementStatus = s.StatementStatus.StatementStatusName;
sm.AmountDue = s.AmountDue;
myStatements.Add(sm);
}
然后我得到了一堆空引用错误,例如Employee.CostCenter 或FiscalPeriod.StartDate 之类的任何子对象。
然后我把它改成:
var statements = db.Statements.Include("Employee.CostCenter.Evp")
.Include("Employee.CostCenter.Svp")
.Include("Employee.CostCenter.Lobmgr")
.Include("FiscalPeriod")
.Include("AdminApprovalStatus")
.Include("StatementStatus").Where(s => s.StatementStatusId == "PAA").ToList();
foreach (var s in statements)
{
StatementModel sm = new StatementModel();
sm.StatmentId = s.StatementId;
sm.EmployeeNumber = s.EmployeeNumber;
sm.FirstName = s.Employee.FirstName;
sm.LastName = s.Employee.LastName;
sm.PlanType = s.Employee.PlanType != null ? s.Employee.PlanType.PlanTypeName : "";
sm.FiscalPeriod = s.FiscalPeriod.StartDate.ToString("yyyy-MM-dd") + " - " + s.FiscalPeriod.EndDate.ToString("yyyy-MM-dd");
sm.CostCenterId = s.Employee.CostCenterId;
sm.RVPName = s.Employee.CostCenter.Evp != null ? s.Employee.CostCenter.Evp.FirstName + " " + s.Employee.CostCenter.Evp.LastName : "";
sm.SVPName = s.Employee.CostCenter.Svp != null ? s.Employee.CostCenter.Svp.FirstName + " " + s.Employee.CostCenter.Svp.LastName : "";
sm.LOBMgrName = s.Employee.CostCenter.Lobmgr != null ? s.Employee.CostCenter.Lobmgr.FirstName + " " + s.Employee.CostCenter.Lobmgr.LastName : "";
sm.AdminApprovalStatus = s.AdminApprovalStatus.ApprovalStatusName;
sm.StatementStatus = s.StatementStatus.StatementStatusName;
sm.AmountDue = s.AmountDue;
myStatements.Add(sm);
}
这可行,但它非常冗长,我不记得曾经在 EF 6 中显式地 .Include 事情,除非这是一个优化问题。
这是在 EF Core 中唯一或最好的方法还是我遗漏了什么?
【问题讨论】:
-
This works, but it's very verbose and I don't recall ever having to explicitly .Include things in EF 6 unless it was an optimization issue这是因为默认情况下在 EF6 中的 DbContext 实例上启用了延迟加载。如果你禁用了这个,那么你还必须使用 .Include。 -
@ChrisSchaller - 如果您仍想为通过投影收到的第一个异常发布解决方案,请告诉我,我将重新提出问题。
-
@Legion - 另请参阅canonical functions,它可以帮助您确定在编写需要通过 linq to entity 转换为 sql 的代码时支持和不支持的内容。
-
@ChrisSchaller 我重新打开了这个问题。
-
@ChrisSchaller 有很多方法可以给猫剥皮。你的回答也完全可以接受。对于 OP:投影可以导致比使用包含更好的查询,但我总是会使用 Sql Profiler 进行检查,并注意读取次数和持续时间以及查询本身。在您的机器上可能没问题,但由于数据量等多种原因导致生产速度变慢。不过,这只是一个旁注。