通过LINQ筛选包含ICollection属性的查询
本文关键字:属性 查询 ICollection 包含 LINQ 筛选 通过 | 更新日期: 2023-09-27 18:07:47
我有2个模型:ApplicationUser和TaskModel
public class ApplicationUser : IdentityUser
{
public virtual ICollection<TaskModel> Tasks { get; set; }
...
}
和
public class TaskModel
{
public virtual ICollection<ApplicationUser> Managers { get; set; }
...
}
我想从数据库中只选择包含一些applicationuser对象在管理器中的记录。然后我尝试使用LINQ
ApplicationUser currentUser = "SomeObject";
var taskModels = db.Tasks.Where(t => t.Managers.Contains(currentUser)).Include(t => t.Autor);
但是Where子句产生了错误。错误信息显示"无法创建一个常量"。ApplicationUser"类型。在这种情况下,它只支持基本类型和枚举类型。"我通过下一个代码
得到我需要的var allTasks = db.Tasks.Include(t => t.Autor).ToList();
List<TaskModel> filterTasks = new List<TaskModel>();
foreach (var task in allTasks)
{
if (task.Managers.Contains(currentUser))
filterTasks.Add(task);
}
return View(filterTasks);
但是我想知道如何通过LINQ语法解决
尝试使用可以指定要比较的列的Any
方法,例如:
var taskModels = db.Tasks
.Where(t => t.Managers.Any(m => m.Id == currentUser.Id))
.Include(t => t.Autor)
.ToList();
不要忘记调用一个方法来执行这个语句,比如ToList()
或FirstOrDefault()
。
你不能使用Contains
与你的ApplicationUser
实例,因为查询是由LINQ到SQL执行(或LINQ到实体,如果你使用实体框架),显然你的数据库不知道你的ApplicationUser
类。
你的第二种方法是有效的,因为在调用ToList()
之后,剩余的代码由LINQ to Objects执行。它等于下面的语句:
db.Tasks.Include(t => t.Autor).ToList().Where(t => t.Managers.Contains(currentUser)).ToList();
注意在Include
之后附加的ToList()
。然而,如果你有很多任务,这可能会执行得很差,因为所有的任务都是从数据库中获取的,然后才进行过滤。
您应该尝试使用@FelipeOriani所示的方法,因为在这种情况下,只从数据库中获取相关的任务。