2016-09-20 2 views
2

У меня есть 2 модели: ApplicationUser и TaskModelфильтр запроса, который содержит ICollection свойства с помощью LINQ

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

и

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

Я хочу, чтобы выбрать из базы данных только та запись, который содержит некоторую AplicationUser объект менеджеров. Чем я попытался с помощью LINQ

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

Но что генерируется ошибка в ИНЕКЕ. В сообщении об ошибке говорится: «Невозможно создать константу типа TaskToDo.Models.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

+0

Добавить '.ToList();' конец вашего linq как 'db.Tasks.Where (t => t.Managers.Contains (currentUser)). Включить (t => t.Autor) .ToList(); ' – SilentCoder

+0

Проблема в том, что вы не можете использовать' contains' в LINQ –

ответ

3

Попробуйте использовать метод Any, где можно указать столбец для сравнения, для образца:

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

не забудьте вызвать метод для выполнения этого утверждения, такие как ToList() или FirstOrDefault().

1

Вы не можете использовать Contains с ApplicationUser экземпляра, поскольку запрос выполняется LINQ to SQL (или LINQ to Entities, если вы используете Entity Framework) и, очевидно, ваша база данных не знает свой ApplicationUser класс.

Ваш второй подход работает, потому что после вызова ToList() оставшийся код выполнен LINQ to Objects. Оно равно следующему утверждению:

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

Обратите внимание на дополнительные ToList() после Include. Однако это может быть очень неудачным, если у вас много задач, так как все ваши задачи извлекаются из базы данных и только потом фильтруются.

Вы должны попытаться использовать подход, показанный @FelipeOriani, поскольку в этом случае из базы данных извлекаются только соответствующие задачи.