【发布时间】:2017-04-25 05:33:47
【问题描述】:
我正在使用 Entity Framework Core 和 Linq 编写查询,以获取对象上 EndDate 属性为 NULL 的所有条目。但是,EF 不会将查询转换为正确的 SQL 以过滤掉 EndDate 不为 NULL 的对象。我正在使用带有这些包的 MySQL 数据库:
"MySql.Data.Core": "7.0.4-IR-191",
"MySql.Data.EntityFrameworkCore": "7.0.4-IR-191",
这是我的查询:
var employees = (from emp in _context.Employees.ToList()
join loc in _context.Locations.ToList()
on emp.HomeLocationId equals loc.LocationId
join rate in _context.EmployeeRates.ToList()
on emp.EmployeeId equals rate.EmployeeId
where rate.EndDate == null
select emp).ToList();
这是我的 EndDate 属性声明:
public DateTime? EndDate { get; set; }
生成的 SQL 根本不包含 WHERE 子句。我已将此查询手动转换为 MySQL,并且效果很好:
SELECT e.FirstName, e.LastName, er.Rate, er.StartDate, er.EndDate
FROM qasdb.employees as e
JOIN qasdb.employeerates as er on er.EmployeeId = e.EmployeeId
JOIN qasdb.locations as l on l.LocationId = e.HomeLocationId
WHERE e.FirstName='Todd' AND er.EndDate is null
这是 EF Core 的问题吗?是否有已知的解决方法可以使 Null 比较起作用?
编辑
这是生成的 SQL。它看起来正在做几个查询:
SELECT e.EmployeeRateId, e.EmployeeId, e.EndDate,
e.LastModifiedBy, e.Rate, e.StartDate FROM employeerates
AS e
SELECT emp.EmployeeId, emp.ActiveFlag, emp.City,
emp.CreateStamp, emp.Email, emp.EmergencyContactName,
emp.EmergencyContactPhone, emp.FirstName,
emp.HomeLocationId, emp.JobClass, emp.LastModifiedBy,
emp.LastName, emp.PhoneNumber, emp.Ssn, emp.State,
emp.Street, emp.UpdateStamp, emp.Zip FROM employees
AS emp
INNER JOIN locations AS loc ON emp.HomeLocationId = loc.LocationId
编辑#2
当我从每一行中删除 ToList() 调用时,会按预期生成 SQL:
SELECT emp.EmployeeId, emp.ActiveFlag, emp.City,
emp.CreateStamp, emp.Email, emp.EmergencyContactName,
emp.EmergencyContactPhone, emp.FirstName,
emp.HomeLocationId, emp.JobClass, emp.LastModifiedBy,
emp.LastName, emp.PhoneNumber, emp.Ssn, emp.State,
emp.Street, emp.UpdateStamp, emp.Zip FROM employees
AS emp
INNER JOIN locations AS loc ON emp.HomeLocationId = loc.LocationId
INNER JOIN employeerates AS rate ON emp.EmployeeId = rate.EmployeeId
WHERE rate.EndDate IS NULL
但是,当我删除 .ToList() 调用时,我的导航属性从 Employee 对象丢失到 EmployeeRates 列表。这是我的 Employee 实体的设置方式:
public class Employee : BaseEntity
{
public int EmployeeId { get; set; }
......
public string JobClass { get; set; }
public int HomeLocationId { get; set; }
//Navigation Properties
public virtual Location HomeLocation { get; set; }
public virtual List<EmployeeRate> EmployeeRates { get; set; }
}
删除 ToList() 调用后,HomeLocation 和 EmployeeRates 对象都返回“null”。
【问题讨论】:
-
能把ef core生成的sql贴一下吗?还有你为什么要在每个 in 中调用 ToList() 方法?
-
删除除最终调用之外的所有
ToList调用,查询应与预期一致。目前您正在告诉 EF 加载内存中的所有表并在那里执行连接/过滤。 -
@IvanStoev,我按照你的建议做了,但是这样做后我的导航属性丢失了 EmployeeRates 对象
-
@H.Herzl,我已经用 SQL 更新了我的帖子。谢谢
标签: mysql entity-framework linq entity-framework-core