Select 多列错误 entity framework(无法创建类型的空常量值)
Select many columns error entity framework (Unable to create a null constant value of type)
我不希望返回所有列,所以我尝试 select 来自 EMPLOYEES 的一些列,当 运行 以下代码时出现错误:
var query = db.EMPLOYEES.AsQueryable();
query = ApplyFilter(query, filter);
var result = query.Select(x => new EMPLOYEE_DTO()
{
PHONE_NO = x.PHONE_NO,
EMAIL = x.EMAIL,
EMP_NO = x.EMP_NO
}).ToList();
private IQueryable<EMPLOYEE> ApplyFilter(IQueryable<EMPLOYEE> query, EmployeesFilter filter)
{
if (!string.IsNullOrEmpty(filter.EMAIL))
query = query.Where(u => u.EMAIL.ToLower().Contains(filter.EMAIL.ToLower()));
return query;
}
错误是:{"Unable to create a null constant value of type 'System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'. Only entity types, enumeration types or primitive types are supported in this context."}
我看到一个 post 说使用 DTO 对象 (EMPLOYEE_DTO) 可以解决问题,但问题仍然存在。
请指教
关于您的 class,您并没有告诉我们很多。我假设 filter
是您本地进程中的一个 EmployeesFilter
对象; db
是一个 DbContext
类型的对象; db.Employees
是 DbSet<Employee>
的对象。
filter
和Employee
都有一个字符串属性Email
每个 DbSet<Employee>
实施 IQueryable<Employee>
。那你为什么打电话给 AsQueryable
?
你的filter
是局部变量。在这种情况下,只有 filter.Email
是重要的。如果此 属性 的值等于 null,则您需要所有 Employees
,否则您需要 Employees
的子集,即只有那些 Employees
具有 Email
值等于过滤器中的 Email
值,忽略大小写。
现在忽略大小写总是很危险的。毕竟,不是每个人的名字都只有字母 A-Z 和 a-z。最好描述你想要什么情况下的无知:序数?当前文化?不变文化?
您似乎想要以下内容:
var query = String.IsNullOrEmpty(filter.Email) ?
db.Employees :
db.Employees
.Where(employee => String.Equals(employee.Email, filter.Email,
StringComparison.InvariantCultureIgnoreCase);
我不确定将其更改为 ApplyFilter 之类的额外函数是否会提高可读性,但如果您确实需要,请将其编写为 IQueryable<Employee>
:
的扩展函数
static IQueryable<Employee> ApplyFilter(this IQueryable<Employee> employees,
EmployeeFilter filter)
{
return String.IsNullOrEmpty(filter.Email) ?
employees :
employees.Where(employee => String.Equals(employee.Email, filter.Email,
StringComparison.InvariantCultureIgnoreCase);
}
任何查询的用法:
IQueryable<Employee> someEmployees = ...
IQueryable<Employee> filteredEmployees = someEmployees.Filter(myFilter);
我故意没有使用 var
,所以你可以看到类型发生了什么。
TODO:通过添加 ToList()
检查此代码是否正确,以查看是否可以获取 Employees
。但是你当然已经这样做了,不是吗?
现在是第二部分。因此,您有一个 returns 和 IQueryable<Employee>
的查询,并且您希望将每个 Employee
投影到 EmployeeDto
。如果您想在查询中执行此操作,则必须确保您的 EmployeeDto
是一个 POCO:具有默认构造函数且仅获取/设置属性的 class。
如果是这种情况,您应该能够执行投影:
var result = query.Select(employee => new EMPLOYEE_DTO()
{
PHONE_NO = employee.PHONE_NO,
EMAIL = employee.EMAIL,
EMP_NO = employee.EMP_NO,
})
.ToList();
我不希望返回所有列,所以我尝试 select 来自 EMPLOYEES 的一些列,当 运行 以下代码时出现错误:
var query = db.EMPLOYEES.AsQueryable();
query = ApplyFilter(query, filter);
var result = query.Select(x => new EMPLOYEE_DTO()
{
PHONE_NO = x.PHONE_NO,
EMAIL = x.EMAIL,
EMP_NO = x.EMP_NO
}).ToList();
private IQueryable<EMPLOYEE> ApplyFilter(IQueryable<EMPLOYEE> query, EmployeesFilter filter)
{
if (!string.IsNullOrEmpty(filter.EMAIL))
query = query.Where(u => u.EMAIL.ToLower().Contains(filter.EMAIL.ToLower()));
return query;
}
错误是:{"Unable to create a null constant value of type 'System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'. Only entity types, enumeration types or primitive types are supported in this context."}
我看到一个 post 说使用 DTO 对象 (EMPLOYEE_DTO) 可以解决问题,但问题仍然存在。
请指教
关于您的 class,您并没有告诉我们很多。我假设 filter
是您本地进程中的一个 EmployeesFilter
对象; db
是一个 DbContext
类型的对象; db.Employees
是 DbSet<Employee>
的对象。
filter
和Employee
都有一个字符串属性Email
每个 DbSet<Employee>
实施 IQueryable<Employee>
。那你为什么打电话给 AsQueryable
?
你的filter
是局部变量。在这种情况下,只有 filter.Email
是重要的。如果此 属性 的值等于 null,则您需要所有 Employees
,否则您需要 Employees
的子集,即只有那些 Employees
具有 Email
值等于过滤器中的 Email
值,忽略大小写。
现在忽略大小写总是很危险的。毕竟,不是每个人的名字都只有字母 A-Z 和 a-z。最好描述你想要什么情况下的无知:序数?当前文化?不变文化?
您似乎想要以下内容:
var query = String.IsNullOrEmpty(filter.Email) ?
db.Employees :
db.Employees
.Where(employee => String.Equals(employee.Email, filter.Email,
StringComparison.InvariantCultureIgnoreCase);
我不确定将其更改为 ApplyFilter 之类的额外函数是否会提高可读性,但如果您确实需要,请将其编写为 IQueryable<Employee>
:
static IQueryable<Employee> ApplyFilter(this IQueryable<Employee> employees,
EmployeeFilter filter)
{
return String.IsNullOrEmpty(filter.Email) ?
employees :
employees.Where(employee => String.Equals(employee.Email, filter.Email,
StringComparison.InvariantCultureIgnoreCase);
}
任何查询的用法:
IQueryable<Employee> someEmployees = ...
IQueryable<Employee> filteredEmployees = someEmployees.Filter(myFilter);
我故意没有使用 var
,所以你可以看到类型发生了什么。
TODO:通过添加 ToList()
检查此代码是否正确,以查看是否可以获取 Employees
。但是你当然已经这样做了,不是吗?
现在是第二部分。因此,您有一个 returns 和 IQueryable<Employee>
的查询,并且您希望将每个 Employee
投影到 EmployeeDto
。如果您想在查询中执行此操作,则必须确保您的 EmployeeDto
是一个 POCO:具有默认构造函数且仅获取/设置属性的 class。
如果是这种情况,您应该能够执行投影:
var result = query.Select(employee => new EMPLOYEE_DTO()
{
PHONE_NO = employee.PHONE_NO,
EMAIL = employee.EMAIL,
EMP_NO = employee.EMP_NO,
})
.ToList();