Перевод Где () в sql

Я видел статью DamienG ( http://damieng.com/blog/2009/06/24/client-side-properties-and-any-remote-linq-provider) о том, как сопоставить свойства клиента с sql. Я прочитал эту статью и увидел в ней большой потенциал. Определенно сопоставление клиентских свойств с SQL - отличная идея.

Но я хотел использовать это для чего-то более сложного, чем просто конкатенация строк. В настоящее время мы пытаемся внедрить многоязычие в наши бизнес-объекты, и я надеялся, что мы можем оставить все существующие запросы linq2sql без изменений и просто изменить код многоязычных свойств, чтобы они фактически возвращали данное свойство в CurrentUICulture.

Первой идеей было изменить эти поля на XML, а затем попробовать Object.Property.Elements().Where(...), но он застрял в Elements(), так как не смог перевести его в sql. Я где-то читал, что поля XML на самом деле рассматриваются как строки, и только на сервере приложений они становятся XElements, так что фильтрация в любом случае будет выполняться на сервере приложений, а не в БД. Честно, это не сработает. Давайте попробуем что-нибудь еще... ТАК, вторая идея состояла в том, чтобы создать таблицу PolyGlots (имя взято из http://weblogic.sys-con.com/node/102698?page=0,1), таблицу PolyGlotTranslations и культуру таблица, на которую PolyGlots будут ссылаться из каждого интернационализированного свойства. Вот как я хотел сказать, например:

private static readonly CompiledExpression<Announcement, string> nameExpression
    = DefaultTranslationOf<Announcement>
        .Property(e => e.Name)
        .Is(e=> e.NamePolyGlot.PolyGlotTranslations
          .Where(t=> t.Culture.Code == Thread.CurrentThread.CurrentUICulture.Name)
          .Single().Value
        );

теперь, к сожалению, здесь я получаю ошибку, что функция Where() не может быть переведена в SQL, что немного разочаровывает, так как я был уверен, что это пройдет. Я предполагаю, что это терпит неудачу, потому что IEntitySet в основном IEnumerable, а не IQueryable, я прав?

Есть ли другой способ использовать класс compiledExpressions для достижения этой цели? Любая помощь приветствуется.

2 ответа

Решение

Что ж, реальная проблема заключалась в том, что используемое Where было не тем из пространства имен System.Linq, а другим, и это не могло быть переведено посетителем выражения ef.

Во-первых, я бы не пытался встраивать расширения XML в SQL. Они были разработаны для разных животных по определенной причине.

При правильной стратегии работы с базой данных вы сможете обойтись без единого набора запросов linq. (Вам может потребоваться настроить их в соответствии с новой моделью.) Например, если у вас есть поле описания, которое отличается в зависимости от языка, чем создавать представление, которое будет возвращать правильное описание в зависимости от выбранного языка. Теперь направьте ваш запрос linq на представление вместо таблиц.

Дополнительная информация: у вас есть только один вид на элемент, который будет содержать многоязычные поля. Каждое многоязычное поле имеет свою собственную таблицу, использующую ключ языковой таблицы и ключ исходного объекта в качестве составного ключа. Представление объединяет все таблицы обратно в одно место для запроса. Теперь скажите, что у нас есть вид продукта. Если я запрашиваю это представление по ProductId = 1, я на самом деле вижу столько копий продукта, сколько существует языков.

Теперь ваши запросы Linq всегда будут содержать параметр для ограничения по языку. Просто убедитесь, что в вашем запросе используется внешнее объединение, так что если описание на каком-либо языке отсутствует, вы все равно получите его обратно. (Или не используйте его, чтобы преднамеренно ограничить элементы теми настройками для выбранного языка.

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

Другие вопросы по тегам