通过LINQ

时间:2016-09-20 11:27:43

标签: c# asp.net-mvc entity-framework linq

我有2个模型:ApplicationUser和TaskModel

public class ApplicationUser : IdentityUser
{
     public virtual ICollection<TaskModel> Tasks { get; set; }
     ...
}

public class TaskModel
{
     public virtual ICollection<ApplicationUser> Managers { get; set; }
     ...
}

我只想从数据库中选择那些在Managers中包含一些AplicationUser对象的记录。 比我尝试使用LINQ

ApplicationUser currentUser = "SomeObject";
var taskModels = db.Tasks.Where(t => t.Managers.Contains(currentUser)).Include(t => t.Autor);

但是在Where子句中产生了错误。错误消息显示&#34;无法创建常量&#34; TaskToDo.Models.ApplicationUser&#34;类型。在这种情况下,它只支持原始类型和枚举类型。&#34; 我通过下一个代码得到了我需要的东西

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语法解决的

2 个答案:

答案 0 :(得分:3)

尝试使用Any方法,您可以指定要比较的列,样本:

var taskModels = db.Tasks
                   .Where(t => t.Managers.Any(m => m.Id == currentUser.Id))
                   .Include(t => t.Autor) 
                   .ToList();

请勿忘记调用方法来执行此语句,例如ToList()FirstOrDefault()

答案 1 :(得分:1)

您不能将ContainsApplicationUser实例一起使用,因为查询是由LINQ to SQL执行的(如果您使用的是实体框架,则为LINQ to Entities)很明显,您的数据库不知道您的ApplicationUser类。

你的第二种方法是有效的,因为在调用ToList()后,剩余的代码由LINQ to Objects执行。它等于以下声明:

db.Tasks.Include(t => t.Autor).ToList().Where(t => t.Managers.Contains(currentUser)).ToList();

请注意ToList()之后的其他Include。但是,如果您有很多任务,这可能会执行得非常糟糕,因为您的所有任务都是从数据库中提取的,之后才会进行过滤。

您应该尝试使用@FelipeOriani显示的方法,因为在这种情况下,只从数据库中提取相关任务。