Вопрос

Я использую аналогичный подход к другим, сохраняя мои объекты LINQ в моем поставщике данных LINQ и возвращая IQueryable для разрешения фильтрации и т.д.Это отлично работает для фильтрации простого объекта по его идентификатору или другому свойству, но у меня возникла проблема с объектом join table, который состоит из других дочерних объектов

    //CoreDBDataContext db = coreDB;
public IQueryable<DTO.Position> GetPositions()    {
     return from p in coreDB.Positions
         select new DTO.Position
             {
             DTO.User = new DTO.User(p.User.id,p.User.username, p.User.firstName,p.User.lastName,p.User.email,p.User.isActive),
             DTO.Role = new DTO.Role(p.Role.id, p.Role.name, p.Role.isActive),
             DTO.OrgUnit = new DTO.OrgUnit(p.OrgUnit.id,p.OrgUnit.name,p.OrgUnit.isActive)
             };

CoreDB.Positions - это мой объект Linq Position, и я возвращаю позицию DTO, которая состоит из User, OrgUnit и роли (базовая таблица представляет собой таблицу объединения с идентификаторами userId, RoleId и OrgUnitID).

Проблема, с которой я сталкиваюсь, заключается в том, что когда я пытаюсь добавить фильтр в Iqueryable, я получаю ошибку SQL, в которой говорится, что для моего DTO недоступен перевод.Пользовательский объект

public static IQueryable<Position> WithUserID(this IQueryable<Position> query, int userID)
    {
        return query.Where(p => p.User.ID == userID);
    }

Я в полной растерянности относительно того, как решить эту проблему, поскольку все мои результаты Google, похоже, относятся к людям, работающим непосредственно с сгенерированными объектами LINQ

Есть какие-нибудь мысли о том, как заставить это работать, или я делаю здесь что-то совершенно неправильное?

Спасибо

Это было полезно?

Решение 3

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

Другие советы

Мне удалось успешно работать с аналогичным подходом:

var courses = from c in Map(origCourses)
where !expiredStatuses.Contains(c.Status)
select c;

Где Карта имеет:

    select new UserCourseListItem
    {
        CourseID = c.CourseID,
        CourseName = cm.CourseName,
        CourseType = c.CourseType.Value
        ...

Как насчет того, чтобы попробовать это с таким типом инициализации (вместо конструкторов).

Ps.это часть рабочего приложения, и expiredStatuses даже связан со сложным выражением.

Обновление 1: Это похоже по сравнению с упомянутым сценарием, потому что:

  • Map возвращает IQueryable, который является объектом POCO.
  • После вызова метода Map, который возвращает IQueryable с объектом POCO, я применяю к нему фильтр.

Linq2SQL понимает только объекты, созданные дизайнером.Ну, это не совсем так, но достаточно близко.

Таким образом, когда вы пишете запросы Linq к объектам Linq2SQL, запрос будет преобразован в действительный SQL при фактическом выполнении запроса, а не при его записи.Поскольку ваши объекты DTO не являются объектами Linq2SQL, Linq2SQL не будет знать, как создать правильный SQL.

Если вы хотите сохранить разделение таким образом, вам нужно найти способ выполнять свои запросы только с задействованными объектами Linq2SQL и сопоставлять результат только с вашими DTO.

Может быть, вы могли бы переписать свой метод запроса на:

Обновить: Параметр должен иметь тип Expression<>, и нет необходимости возвращать IQueryable<>.Спасибо Фредди за указание.

public IEnumerable<DTO.Position> FindPositions(Expression<Func<Position, bool>> criteria)
{
    return from p in coreDB.Positions
           where criteria.Invoke(p)
           select new DTO.Position
                      {
                          User = new DTO.User(p.User.id, p.User.username, p.User.firstName, p.User.lastName,
                                       p.User.email, p.User.isActive),
                          Role = new DTO.Role(p.Role.id, p.Role.name, p.Role.isActive),
                          OrgUnit = new DTO.OrgUnit(p.OrgUnit.id, p.OrgUnit.name, p.OrgUnit.isActive)
                      };
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top