1


1

Where()からSQLへの翻訳

クライアントプロパティをsqlにマップする方法について、DamienGの記事(http://damieng.com/blog/2009/06/24/client-side-properties-and-any-remote-linq-provider)を参照しました。 私はこの記事を読んで、その中に大きな可能性を見出しました。 クライアントプロパティをSQLに確実にマッピングするのは素晴らしいアイデアです。

しかし、文字列を連結するよりも少し複雑なものにこれを使用したかったのです。 Atmはビジネスオブジェクトに多言語を導入しようとしています。既存のすべてのlinq2sqlクエリをそのまま残し、多言語プロパティのコードを変更するだけで、CurrentUICultureで指定されたプロパティが実際に返されるようにしたいと思います。

最初のアイデアは、これらのフィールドをXMLに変更してからObject.Property.Elements()。Where(…​)を試すことでしたが、Elements()に留まり、sqlに変換できませんでした。 XMLフィールドは実際には文字列と見なされ、アプリサーバー上でのみXElementになるため、この方法では、DBではなくアプリサーバー上でフィルタリングが行われます。 公正な点、それはこのように機能しません。 他のことを試してみましょう…​ 2番目のアイデアは、PolyGlotsテーブル(http://weblogic.sys-con.com/node/102698?page=0,1から取られた名前)、PolyGlotTranslationsテーブル、およびPolyGlotsがあるCultureテーブルを作成することでした各国際化プロパティから参照されます。 このように私は例えば言いたかった:

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

残念ながらここでは、Where()関数をsqlに変換できないというエラーが表示されます。これは少し残念なことです。 私はそれが失敗していると思います、IEntitySetは基本的にIQueryableではなくIEnumerableです、私は正しいですか?

この目的を達成するために、compiledExpressionsクラスを使用する別の方法はありますか? 任意の助けをいただければ幸いです。

2 Answer


1


まず、XML拡張をSQLに取り組もうとはしません。 それらは理由のために異なる獣のために設計されました。

適切なデータベース戦略があれば、linqクエリの単一のセットで逃げることができるはずです。 (新しいモデルに合わせて調整する必要がある場合があります。)たとえば、言語に応じて異なる説明フィールドがある場合、選択した言語に基づいて正しい説明を返すビューを作成します。 次に、linqクエリがテーブルではなくビューを指すようにします。

追加情報:多言語フィールドを含むアイテムごとに1つのビューのみがあります。 各多言語フィールドには、言語テーブルキーと元のオブジェクトのキーを複合キーとして使用する独自のテーブルがあります。 ビューは、すべてのテーブルを1つの場所に結合してクエリします。 製品ビューがあるとしましょう。 ProductId = 1でそのビューをクエリすると、実際には言語の数だけ製品のコピーが表示されます。

これで、Linqクエリには常に言語ごとに制限するパラメーターが含まれます。 クエリで外部結合を使用して、言語の説明が欠落している場合でもそれを取得できるようにしてください。 (または、選択した言語のセットアップにアイテムを意図的に制限するために使用しないでください。

ストアドプロシージャを作成して、ビューを更新してテーブルのように機能させる機能を開くことができます。 (または、ほとんどのARMフレームワークでこれを行うには、ストアドプロシージャをそこに接続します。)


0


実際の問題は、使用される場所がSystem.Linq名前空間のものではなく、別のものであり、efの式ビジターによって翻訳できないことでした。