我正在开发一个使用实体框架的 ASP.NET MVC 项目。
我需要将从数据库中提取的值投影到PropertyValue
类型,如下所示:
public class PropertyValue {
public string StringValue { get; set; }
public bool? BoolValue { get; set; }
public int? IntValue { get; set; }
}
大多数时候,这很容易。要过滤“First Name”=“John”且“Is Archived”= true 的所有用户,我可以这样做:
usersQuery
.Where(u =>
new PropertyValue {
StringValue = u.FirstName,
BoolValue = null,
IntValue = null
}.StringValue == "John")
.Where(u =>
new PropertyValue {
StringValue = null,
BoolValue = u.IsArchived,
IntValue = null
}.BoolValue == true);
显然,这是一个看起来很荒谬的查询,但我正在根据用户输入逐段构建这些查询。这些查询需要可组合,这就是为什么我必须显式设置所有未使用的属性PropertyValue
为空,我必须将它们全部设置为相同的顺序。如果我不这样做,我将从实体框架收到错误,指出 PropertyValue 存在于查询中两个结构不兼容的初始化中。
System.NotSupportedException:类型“UMS.Utilities.PropertyValue”出现在单个 LINQ to Entities 查询中的两个结构不兼容的初始化中。可以在同一查询中的两个位置初始化类型,但前提是在两个位置设置相同的属性并且以相同的顺序设置这些属性。
这不是问题,我只需确保所有属性都显式设置为 null 即可。当我必须向我的属性添加另一个属性时,问题就出现了PropertyValue
输入,以便能够检索 ID 列表(在我的例子中,检索用户的所有选定角色,即“管理员”、“监护人”、“教师”、“学生”)
我修改了我的PropertyValue
能够存储 Guid 列表的类:
public class PropertyValue {
public string StringValue { get; set; }
public bool? BoolValue { get; set; }
public int? IntValue { get; set; }
public IEnumerable<Guid> GuidValues { get; set; }
}
我现在可以像这样查询用户角色:
usersQuery
.Select(u => new PropertyValue {
StringValue = null,
BoolValue = null,
IntValue = null,
GuidValues = u.UserRoles.Select(ur => ur.Role_ID)
});
效果很好。提取名字现在看起来像这样:
usersQuery
.Select(u => new PropertyValue {
StringValue = u.FirstName,
BoolValue = null,
IntValue = null,
GuidValues = null
});
但我收到以下错误:
System.NotSupportedException:无法创建“System.Collections.Generic.IEnumerable`1[[System.Guid,mscorlib,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089]]”类型的空常量值。此上下文中仅支持实体类型、枚举类型或基本类型。
所以我无法在 EF 中创建空枚举。但我不能仅仅忽略属性的初始化,否则我会得到结构不兼容的错误。我试过做GuidValues = Enumerable.Empty<Guid>()
相反,但我也无法在 EF 上下文中执行此操作。
如何解决此问题并在 EF 投影中创建 null 或空可枚举?