paginatedlist выдает ошибку «Локальная последовательность не может использоваться в реализациях операторов запросов LINQ to SQL, кроме оператора Contains» - PullRequest
0 голосов
/ 10 апреля 2011

Я посмотрел здесь: Исключение LINQ To SQL: локальная последовательность не может использоваться в реализации операторов запросов LINQ to SQL, кроме оператора Contains

и здесь: LINQ для заполнения диапазона

но я не могу понять это. Я основал свой диспетчер задач на проекте NerdDinner. Вместо FindUpcommingDinners у меня есть метод ниже:

    Public Function FindAllTeamTasks(ByVal TeamRole As String) As IQueryable(Of Task) Implements ITaskRepository.FindAllTeamTasks

        Return From task In db.Tasks
               Join usrs In System.Web.Security.Roles.GetUsersInRole(TeamRole)
               On task.TaskAssignedToID Equals usrs
               Order By task.InsertDateTime _
               Select task
    End Function

Когда результат передается в Paginatedlist в качестве источника, он выдает ошибку «Local sequence not ...». Ответ может быть и здесь, но я не могу понять это. Пожалуйста, помогите.

ASP.NET MVC2 LINQ - Шаблон репозитория, куда должен идти код пагинации?

Ответы [ 2 ]

0 голосов
/ 10 апреля 2011

Всякий раз, когда вы используете Linq to SQL, ваш запрос должен иметь возможность преобразовываться в SQL для выполнения в вашей базе данных.Поставщик Linq для Linq to SQL знает, как это сделать только для очень определенных операций, которые будут происходить за пределами базы данных.Так, например, Linq to SQL понятия не имеет, что делать с

Join usrs In System.Web.Security.Roles.GetUsersInRole(TeamRole)

, потому что GetUsersInRole - это не (для Linq) таблица в базе данных, а скорее коллекция в вашемapplication.

Как упоминается в сообщении об ошибке, существует «исключение» в том, что в некоторых случаях Linq to SQL знает, что делать с Contains (превращая его в IN в SQL, если яНапомним) для коллекции, которая не находится в базе данных.Имея это в виду, вы можете превратить ваш запрос в нечто вроде (извините, это на C #, но я надеюсь, что вы можете перевести):

string[] users = System.Web.Security.Roles.GetUsersInRole(TeamRole);

return db.Tasks
         .Where<Task>(t => users.Contains<string>(t.TaskAssignedToID))
         .OrderBy<Task, DateTime>(t => t.InsertDateTime)
         .AsQueryable<Task>();

Теперь, если ваше объединение было там, потому что TaskAssignedToID была коллекциейа не просто строка (я не знаком с моделью, которую вы используете, извините), вместо этого вам может потребоваться сделать что-то вроде

string[] users = System.Web.Security.Roles.GetUsersInRole(TeamRole);

return db.Tasks
         .Where<Task>(t => t.TasksAssignedToID.Any<string>(i => users.Contains<string>(i)))
         .OrderBy<Task, DateTime>(t => t.InsertDateTime)
         .AsQueryable<Task>();

Я не уверен на 100%, что Linq to SQLХорошо с Any - я работаю в основном с Linq to Entities - но я надеюсь, что в этом есть какой-то смысл.

0 голосов
/ 10 апреля 2011

Нельзя использовать результат GetUsersInRole() в соединении с таблицей базы данных через LINQ to SQL.Вы можете попробовать это вместо:

  Dim usrs = System.Web.Security.Roles.GetUsersInRole(TeamRole)

  Return From task In db.Tasks                      _
         Where usrs.Contains(task.TaskAssignedToID) _
         Order By task.InsertDateTime               _
         Select task
...