LinqToSQL - не поддерживается перевод на SQL - PullRequest
1 голос
/ 31 января 2009

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

У меня есть две таблицы БД:

table Parent
{
   ParentId
}

table Child
{
   ChildId
   ParentId [FK]
   Name
   Age
}

Они имеют эквивалентные классы LinqToSQL в моем проекте, однако я написал два пользовательских класса моделей, которые я хочу использовать в своем интерфейсе вместо использования классов LinqToSQL.

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

На уровне хранилища я возвращаю IQueryable по:

return from data in _data.Children
       select new CustomModel.Child
       {
          ChildId = data.ChildId,
          ParentId = date.ParentId
       };

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

return _repository.GetAllChildren().Where(c => c.Parent.ParentId == parentId).ToList();

Итак, на данный момент, я получаю, что метод не поддерживает ошибку перевода в sql, когда я запускаю все, так как свойство c.Parent моей пользовательской модели не может быть преобразовано. [Свойство c.Parent является ссылкой на объект в связанном классе родительской модели.]

Это все имеет смысл, поэтому мой вопрос таков:

Можете ли вы предоставить процесс запроса с некоторыми правилами, которые будут преобразовывать выражение предиката в правильное кусок SQL для запуска в базе данных и, следовательно, не вызвать ошибку?

Я до сих пор не проделал большую работу с linq, так что простите мне отсутствие опыта, если я не объяснил это достаточно хорошо.

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

Большое спасибо, если кто-нибудь может помочь.

1 Ответ

1 голос
/ 31 января 2009

Во-первых, возникает вопрос: почему хранилище возвращает типы пользовательского интерфейса? Если бы репо вернуло типы баз данных, это не было бы проблемой. Рассмотрите возможность рефакторинга, чтобы репо работало только с моделью данных, а пользовательский интерфейс выполняет перевод в конце (после любой композиции).


Если вы имеете в виду «и перевести его в базу данных» - тогда, по сути, нет. Составные запросы могут использовать только типы, определенные в модели LINQ-to-SQL, и несколько поддерживаемых стандартных функций. Нечто подобное появилось недавно по связанному вопросу, см. Здесь .

Для некоторых сценариев (необычная логика, но с использованием типизированных, определенных в модели LINQ-to-SQL), вы можете использовать UDF в базе данных и писать логику самостоятельно (в TSQL) - но только с LINQ-to- SQL (не EF).

Если громкость невелика, вы можете использовать LINQ-to-Objects для последнего бита. Просто добавьте .AsEnumerable() перед затронутым Where - это вернет эту логику назад в управляемый код .NET (но предикат не будет использоваться в запросе к базе данных):

return _repository.GetAllChildren().AsEnumerable()
            .Where(c => c.Parent.ParentId == parentId).ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...