問題タブ [expression-trees]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
4867 参照

.net - 重要な IQueryable から Linq を SQL クエリにコンパイルする

CompiledQuery.Compile メソッドを使用して、IQueryable に関連付けられた Expression をコンパイルする方法はありますか? 現在、背後に非常に大きな式ツリーを持つ IQueryable があります。IQueryable は、それぞれがコンポーネントを提供するいくつかのメソッドを使用して構築されました。たとえば、2 つのメソッドが IQueryables を返し、それらが 3 つ目のメソッドに結合される場合があります。このため、compile() メソッド呼び出し内で式全体を明示的に定義することはできません。

式を someIQueryable.Expression としてコンパイル メソッドに渡したいと思っていましたが、この式はコンパイル メソッドで必要な形式ではありません。クエリをコンパイルメソッドに直接入れることでこれを回避しようとすると、次のようになります。

datacontext 内で呼び出しフォームを作成すると、「getUsers がストアド プロシージャまたはユーザー定義関数としてマップされていません」というエラーが表示されます。ここでも、getUsers メソッドの内容をコンパイル呼び出しを行う場所にコピーすることはできません。これは、他のメソッドを使用するためです。

「getUsers」から返された IQueryable の Expression を Compile メソッドに渡す方法はありますか?

更新 しました 次のコードを使用して、システムに自分の意志を強制しようとしました:

foo は次のようになります。

{System.Data.Linq.SqlClient.SqlProvider+OneTimeEnumerable`1[Model.Entities.User]}

結果を展開してクエリを実行する代わりに、「操作によりランタイムが不安定になる可能性があります」というメッセージしか表示されないため、foo で結果を表示するオプションはありません。

SQL 文字列を 1 回だけ生成し、後続のリクエストでパラメータ化されたコマンドとして使用する方法を見つける必要があるだけです。これは、データ コンテキストで GetCommand メソッドを使用して手動で行うことができますが、すべてのパラメータを明示的に設定する必要があります。この特定のクエリの複雑さを考えると、これは数百行のコードです。

更新しました

ジョン・ラスクが最も有益な情報を提供してくれたので、私は彼にこの件での勝利を与えました。ただし、いくつかの追加の調整が必要であり、途中で遭遇した他のいくつかの問題があったため、答えを「拡張」したいと思いました. まず、「操作によりランタイムが不安定になる可能性があります」というエラーは、式のコンパイルが原因ではなく、実際には式ツリーの奥深くにあるキャストが原因でした。.Cast<T>()一部の場所では、アイテムが正しいタイプであっても、アイテムを正式にキャストするためにメソッドを呼び出す必要がありました。詳細は省きますが、これは基本的に、いくつかの式が 1 つのツリーに結合され、各分岐が異なる型 (それぞれが共通クラスのサブ型) を返す可能性がある場合に必要でした。

不安定化の問題を解決した後、コンパイルの問題に戻りました。ジョンの拡張ソリューションはほぼ完成しました。ツリーでメソッド呼び出し式を探し、メソッドが通常返す基になる式に解決しようとしました。式への参照は、メソッド呼び出しではなく、プロパティによって提供されました。したがって、展開を実行する式ビジターを変更して、これらの型を含める必要がありました。

この方法はすべての場合に適切であるとは限りませんが、同じ苦境に陥った人には役立つはずです。

0 投票する
3 に答える
9106 参照

c# - C# 式ツリーを詳細に学習するための最適なリソースは何ですか?

この質問を最初に入力したとき、誰かがすでにこの質問をしているに違いないと確信して、重複した質問を見つけるために入力しました。私の計画は、この質問を投稿する代わりに、それらのだまされたリンクをたどることでした。しかし、この質問は私が見る限り以前に尋ねられたことはありません...「関連する質問」リストには表示されませんでした。

C# の式ツリーを深く理解するために見つけた最高のリソース (記事、書籍、ブログ投稿など) は何ですか? 私は彼らの能力に驚かされ続けており、今では「OK、十分な驚きです。今すぐやめて、これらの分野で博士号を取得したい」と言っているところまで来ています。機能を体系的かつ体系的にカバーし、それらを使用して何ができるかの詳細な例を紹介する資料を探しています。

注: ラムダ式について話しているのではありません。私は、Expression< T > と、それに付随し、そこから生じるすべてのものについて話しているのです。

ありがとう。

0 投票する
1 に答える
2171 参照

.net - 式のパラメータの型を変更する方法は?

ドメインでPOCOSを使用しているため、リポジトリでPOCOSのタイプの式フィルタを受信し、式のパラメータをLINQテーブルのタイプに変更できるようにしたいと考えています。フィールドの名前は私のメンバーなので、メンバーと定数に分割することで、1 と 2 のラムダ条件でこれを達成できました。さらに条件を追加すると、バイナリ式が再帰的に解析されます。

これが私が終わった方法です、これを達成する簡単な方法はありますか

私がそれを変える方法

0 投票する
5 に答える
4144 参照

c# - IQueryable クエリの一部を実行し、残りを Linq for Objects に任せる

選択したデータソースからデータを正常に取得する Linq プロバイダーがありますが、フィルター処理された結果セットを取得したので、Linq to Objects が式ツリーの残りの部分を処理できるようにすることです (結合、結合など)。投影など)

私の考えでは、IQueryProvider を含む式定数を ExpressionVisitor を介して結果セット IEnumerable に置き換え、その新しい式を返すことができると考えていました。また、私の IQueryable から IEnumerable のプロバイダーを返します...しかし、これはうまくいかないようです:-(

何か案は?

編集:ここにいくつかの良い答えがありますが、フォームを考えると...

私のプロバイダーでは、Customers と Orders から 2 つの結果セットを簡単に取得できます。データが SQL ソースからのものである場合は、SQL Join 構文を作成して渡すだけですが、この場合、データは SQL ソースからのものではないため、コードで結合を行う必要があります...しかし、私が言ったように、私は2つの結果セットを持っており、Linq to Objectsは結合を行うことができます...(そして後で投影)式定数MyProv.Table<Customer>を置き換えるだけで本当にいいでしょうandMyProv.Table<Order>を使用して、プロバイダーに式を処理させます...それは可能ですか? どうやって?List<Customer>List<Order>List<>

0 投票する
4 に答える
21092 参照

c# - (ラムダ式) 文字列を解析して Action デリゲートにする簡単な方法はありますか?

渡されたアクション デリゲートに基づいて「アカウント」オブジェクトを変更するメソッドがあります。

これは意図したとおりに機能します...

...しかし、今私が試してみたいのは、次のような方法です:

その後、次のように使用できます。

アカウント「Account1234」を無効にします。

私はlinq dynamic query libraryを見てきました.Funcタイプのデリゲートを除いて、多かれ少なかれ私が望むことをしているようですが、式ツリーなどに関する私の知識は、私が何を達成するかを理解するのに十分ではありません.欲しいです。

私がやりたいことを簡単に行う方法はありますか、それとも式を適切に学習して大量のコードを書く必要がありますか?

(これを行う理由は、ユーザーがラムダ式を指定して変更を実行できる PowerShell スクリプトからアカウント オブジェクトを簡単に一括更新できるようにするためです。)

0 投票する
6 に答える
12383 参照

c# - C#LINQ to SQL:このジェネリックGetByIDメソッドのリファクタリング

私は次の方法を書きました。

基本的に、これはGenericクラスのメソッドであり、TはDataContextのクラスです。

このメソッドは、T(GetTable)のタイプからテーブルを取得し、入力されたパラメーターの最初のプロパティ(常にID)をチェックします。

これに伴う問題は、プロパティでを実行するために最初に要素のテーブルをリストに変換する必要がGetTypeあったことですが、テーブルのすべての要素を列挙してに変換する必要があるため、これはあまり便利ではありませんList

ToListテーブル全体でを回避するために、このメソッドをリファクタリングするにはどうすればよいですか?

[アップデート]

テーブルで直接実行できない理由Whereは、次の例外を受け取ったためです。

メソッド'System.Reflection.PropertyInfo[] GetProperties()'には、SQLへの変換がサポートされていません。

GetPropertiesSQLに変換できないためです。

[アップデート]

Tのインターフェイスを使用することを提案する人もいますが、問題は、Tパラメーターが[DataContextName] .designer.csで自動生成されるクラスになるため、インターフェイスを実装できないことです(そして、 LINQのこれらすべての「データベースクラス」のインターフェイス。また、DataContextに新しいテーブルを追加するとファイルが再生成されるため、書き込まれたすべてのデータが失われます。

だから、これを行うためのより良い方法がなければなりません...

[アップデート]

Neil Williamsの提案のようにコードを実装しましたが、まだ問題があります。コードの抜粋は次のとおりです。

インターフェース:

DataContext [コードの表示]:

一般的な方法:

この行で例外がスローされています:return table.SingleOrDefault(e => e.ID.Equals(id));そして例外は次のとおりです:

System.NotSupportedException: The member 'MusicRepo_DataContext.IHasID.ID' has no supported translation to SQL.

[更新]解決策:

DenisTrollerの投稿された回答とCodeRantブログの投稿へのリンクの助けを借りて、私はついに解決策を見つけることができました:

0 投票する
3 に答える
1245 参照

.net - 式ツリーのハッシュ

私は、疑似インテリジェント キャッシングをLINQ クエリ プロバイダーに組み込むことに取り組んでいます。私が(理想的には)やりたいことは、特定のクエリの式ツリーをいくつかのシナリオでキャッシュキーとして使用することです。ただし、オブジェクト グラフ全体を格納したくないので、式ツリーからハッシュサムのような値を取得する簡単な方法は何ですか? または、間違った方向に進んでいる場合、より良い選択肢はありますか?

0 投票する
3 に答える
9119 参照

c# - C#:任意の文字列を解析して式ツリーにする方法は?

私が取り組んでいるプロジェクトでは、かなり奇妙なデータ ソースを使用する必要があります。「クエリ」を指定すると、DataTable が返されます。ただし、クエリは従来の文字列ではありません。それはもっと似ています...私が望む基準を定義する一連のメソッド呼び出しです。これらの行に沿ったもの:

本質的に、それはすべての標準的なもの (ブール演算子、括弧、いくつかの関数など) をサポートしますが、それを記述するための構文は非常に冗長で、日常の使用には不快です。

"Column1 = 123 AND Column2 < 456"与えられた式 ( など) を解析し、それを上記の関数呼び出しに変換する小さなパーサーを作成したかったのです。また、そこにパラメータを追加できればいいので、インジェクション攻撃から保護されます。一番上の最後の小さな砂糖は、解析結果をキャッシュし、同じクエリが別のオブジェクトで再実行されるときにそれらを再利用できるかどうかです。

だから私は疑問に思っていました-これに使用できる既存のソリューションはありますか、それとも独自の式パーサーを展開する必要がありますか? それほど複雑ではありませんが、コーディングに 2 ~ 3 日かかり、修正するバグの山を節約できれば、それだけの価値があります。