diff --git a/jp/ai/getting-started.md b/jp/ai/getting-started.md index 51982c4..dda4ac2 100644 --- a/jp/ai/getting-started.md +++ b/jp/ai/getting-started.md @@ -1,262 +1,106 @@ --- -title: App Builder AI を使用した作業の開始 -_description: 想像できるものなら、App Builder AI が作成します。単純で繰り返しの多い作業を 自動化し、開発チームがカスタム機能に集中できるようにして、実際のアプリを迅速に提供できます。 -_keywords: App Builder AI, Infragistics, Ignite UI +title: App Builder AI を使用した作業の開始 +_description: App Builder の AI Chat 機能を使用すると、自然言語を使用してマルチ ビュー アプリの構築、データの生成、テーマの作成などを行うことができます。 +_keywords: App Builder AI, AI Chat, インフラジスティックス, Ignite UI, AI 生成 _language: ja --- # App Builder AI を使用した作業の開始 -このガイドでは、App Builder で新しく導入された AI を活用したコンテンツ生成について説明します。 +App Builder の AI チャット機能は、ナビゲーション付きのマルチ ビュー アプリの構築を支援します。既存の UI をコンテキスト内で簡単に反復編集でき、アプリの他の部分を壊すことなく作業可能です。画像やスクリーンショットをアップロードして、カスタム テーマを適用した完全な UI を作成できます。 -AI 機能は現在**プレビュー**としてのみ利用可能であり、まだ最終的なデザインではありません。これらの AI 機能は現在も改善中であり、フィードバックを収集することを目的としています。そのため、完全に洗練されておらず、ユーザーの入力に基づいて進化する可能性があります。**プレビュー**機能にはここからアクセスできます: https://preview.appbuilder.dev/ +AI チャット パネルは、App Builder 内のすべての AI 駆動型の生成とアシストの中心的なハブです。 -## ビューの生成 + -App Builder の AI を活用したビューの生成機能は、従来のレイアウト ピッカーに代わる強力な選択肢を提供します。フリーテキストのユーザー プロンプトと複数のプロンプト パターンを活用することで、ユーザーは高度にカスタマイズされたビューを生成し、それを完全に機能するアプリケーションに自動的に変換できます。このアプローチは、アプリ ビューの作成を加速するだけでなく、UI デザインを簡素化し、さまざまなレベルの技術レベルのユーザーがインターフェースを生成できるようにします。 +## 主要機能 - -

ログイン画面

+### 1. エンドツーエンドのアプリケーションと UI の生成 -### プロンプト ベースの生成 +AI 機能は、自然言語から完全なアプリケーションを生成できるようになりました。これにはマルチ ページ構造、ビューポート、ナビゲーション、テーマなどが含まれます。ダッシュボード、ランディング ページ、製品リスト、e コマース、またはログイン/登録画面などの完全な画面を構築します。すべての出力は、一貫性のある高品質な UI のために Ignite UI のエンタープライズ グレードのコンポーネントを使用して作成されます。 -**手順 1**: GenAI ダイアログにフリーテキスト プロンプトを入力します。 + -**手順 2**: 生成された結果を **[プレビュー]** セクションで表示します。 +### 2. スマートなコマンドと構造化された実行 -**手順 3**: [プレビュー] セクションのプラス ボタンを使用して操作を適用します。 +精度と一貫性を保証する強力なコマンド エンジンです。 -- **コンテンツの追加** – 現在のビューの最後にコンテンツを追加します。 -- **新しいビューの作成** – 新しく生成されたコンテンツを別のビュー ページに追加します。 -- **コンテンツの置換** – 現在のビューで選択されたコンポーネントを生成された出力に置き換えます。別のものに変換したいセクション/レイアウト/コンポーネントを選択し、もう一度 GenAI ダイアログを開いてプロンプトを配置し、[追加] ボタン -> [コンテンツの置換] オプションをクリックします。 +- **CREATE**: アプリ、ビュー、コンポーネント、テーマ、ビューポート、データ ソース、画像を作成します。 +- **UPDATE**: コンポーネント、テーマ、画像、プロパティを変更します。 +- **DELETE**: キャンバスから要素を安全に削除します (ビューとテーマは除く)。 -**プレースホルダー値と幅 200px を指定して、要素を「検索」タイプの入力に置き換える例:** +このプロセスには、プレビュー、ステップ バイ ステップの実行、およびエラーが発生した場合の明確な診断が含まれます。 - -

コンテンツの置換の置換

+### 3. AI は実際の動作するデータを理解して生成 -ユーザーは、さまざまなコンテキスト メニュー オプションを使用して、ビューを繰り返し生成および調整できます。動作は**現在のビューの状態**と**選択されたコンポーネント**に依存します。 +自然言語の説明から、実際の動作するデータを理解して生成します。データ ソースを自動的に作成し、JSON を生成し、スキーマを検出し、手動設定なしでコンポーネントにデータをバインドします。また、フィールドをマッピングし、変数を作成し、バインディングをインテリジェントに構成して、すべてがすぐに使える状態にします。 -| コンテキスト | コンポーネントが選択されていません | レイアウト コンテナーが選択されています | コンテナー以外のコンポーネントが選択されています | -| ------------------- | ----------------------------------------- | ----------------------------------------------- | --------------------------------------------------- | -| **コンテンツの追加** | ビューの末尾にコンテンツを追加します | 選択したコンテナーにコンテンツを追加します | 最初に選択されたコンポーネントの前にコンテンツを挿入します | -| **コンテンツの置換** | 現在のビューのコンテンツを完全に置き換えます | 選択されたコンテナーの内容を完全に置き換えます | 選択されたすべてのコンポーネントを置き換えます | -| **新しいビューの作成** | 新しいマスター ビューを作成します | 新しいマスター ビューを作成します | 新しいマスター ビューを作成します | - -> [!NOTE] -> **元に戻す/やり直し**は、**追加**および**置換**アクションではサポートされていますが、新しいビューの作成では**サポートされていません**。 -> 生成されたコンテンツにビュー コンテナーが含まれる場合は、**子ビューを作成できます**。 -> **AI によって生成されたビュー**と**手動で作成されたビュー**の両方を売り返し改良できます。 + - +### 5. 画像からアプリケーションへの生成 -### ユース ケースの例 +AI のコンテキスト認識解釈により、アップロードされた画像から完全なアプリケーションを生成できます。また、プロンプトから画像を作成し、必要に応じてデザインに自動的に配置することもできます。これにより、ビジュアルの探索と最終的な UI の作成の両方がより速く、より直感的になります。 -#### 例 1: ログイン画面 + -プロンプト: + -``` -Create a detailed login screen -``` +## マルチ モード AI チャット - -

ログイン画面

- -AI 出力 - Angular テンプレート: - -```html -
-

Login

-

Enter your username and password to log in.

-
- - - - Username - - - - - Password - - Remember me - - Forgot password? - Create an account -
-
-``` - - -

Blazor コードを使用したログイン画面

- -#### 例 2: カーサービス ビュー +AI チャットはインテント分類を実行し、プロンプトがコンテンツの生成 (コンポーネントの作成や編集など) を目的としているか、製品関連のヘルプを求めているかを判断します。 -プロンプト: +- **Analyze モード (Submit)**: ユーザーの意図を検出し、リクエストをルーティングします (サポート vs. 生成)。 +- **Generate モード (Generate)**: アプリケーション、ビュー、レイアウト、コンポーネント、テーマ、データを作成します。 +- **Support モード (Ask)**: ドキュメントとヘルプ コンテンツに基づいて質問に回答します。 -``` -Design a booking screen for an auto-service shop app that allows customers to schedule common car services. The screen should include sections for vehicle selection, available services, appointment scheduling, and a booking summary. Users first select their car make, model, and year from dropdown menus. Then, they choose a service from a grid of six cards, each displaying the service name, price, description, and a "Select" button. Next, they pick a date from a calendar and select an available time slot from a grid of eight buttons. Finally, the booking summary lists the selected services and provides "Confirm Booking" and "Cancel" buttons. The layout should follow a structured column and row format, ensuring a seamless flow from vehicle selection to appointment confirmation. -``` +この機能強化により、App Builder はコンテキストに応じて応答し、コンテンツ生成とアプリ内サポートの間でシームレスに切り替えることができます。 - -

自動車整備工場

- -AI 出力 - Angular テンプレート: - -```html -
-

- Vehicle Selection -

- - - Toyota - - - Honda - - - Ford - - - Select your car's make - - - - Corolla - - - Civic - - - Mustang - - - Select your car's model - -``` - -アプリのプレビューは次のとおりです。 - - -

自動車整備工場のプレビュー

- -### より正確な結果を得るための便利なパターン - -> [!NOTE] -> これらのパターンを推奨事項として考慮し、通常のプロンプトの説明のフレーズをいつでも使用できます。 - -#### パターン 1: レイアウトとコンポーネントの組み合わせプロンプト - -レイアウトと詳細なコンポーネント構成を組み合わせた、より構造化された出力の場合、複数のセクションを含む全体的な画面デザインを指定できます。次に例を示します。 - -``` -A login screen with: -row layout - col layout - title: Login - text: Please enter your email and password to sign in - form: - input: email - input: password - switch: remember me - button: login - row layout - text: Dont have an account? - link: sign up - image -``` - -結果: - - -

ログイン画面

- -#### プロンプト 2 - -構造化された同等のプロンプト - -``` -Generate a view with this layout: -nav bar -horizontal group - nav drawer (isOpen=true, pin=true) - 5 items - vertical group - title (color=red) - horizontal group - 4 cards with media + -``` - -結果: - - -

複合ビュー

- -## 追加の AI 機能 - - - -### 画像の生成 - -**手順:** - -1. **AIGen** ダイアログを開き、**[Image]** タブに移動します。 -2. 画像を説明するプロンプトを入力するか、**プロンプトの例**を使用します。 -3. 結果に満足したら、**[追加]** をクリックして**画像ライブラリ**に保存します。 -これで、プロジェクト内で使用できます。 +## リッチな会話エクスペリエンス - -

画像の生成

+会話型ワークスペースは、アプリを構築するための柔軟でインタラクティブな環境を提供します。 -### データ ソースの生成 +- **Chat コンポーネント**: Ignite UI Chat コンポーネントは、テキスト、音声認識、画像生成とアップロードの両方をサポートします。 +- **セッション管理**: セッションは名前変更、検索、ピン固定、削除が可能で、長いワークフロー全体で整理された状態を保つことができます。 +- **ピン固定されたチャット履歴**: 重要なセッションにすばやく戻ることができます。 +- **画像アップロード**: ドラッグ アンド ドロップ、貼り付け、または従来の選択コピー -> 貼り付けのサポートにより簡単です。 +- **ガイダンス**: AI は、構築時に役立つフォローアップの提案、プロンプト、次のステップを推奨します。すべてのアクションには、コマンド プレビュー、実行の進行状況、実用的なエラーの説明が付属しています。何かを改良する必要がある場合、再試行オプションによりプロセスが簡単で許容的になります。 -**手順:** + -1. **AIGen** ダイアログを開き、**[Data]** タブに移動します。 -2. 必要なデータを説明するプロンプトを入力します。 -3. インスピレーションを得るには、**[プロンプトの例]** ボタンをクリックしてください。 -4. **[追加]** をクリックして、新しいデータ ソースを作成するか、既存のデータ ソースに追加します。 +### 音声認識 - -

データ ソースの生成

+音声認識サポートにより、AI との対話がさらに直感的になります。プロンプト エリアのマイク ボタンをクリックし、指示を話すと、テキスト フィールドに直接文字起こしされるのを確認できます。ハンズフリー ワークフローや迅速なアイデアのキャプチャに最適です。 -## ご意見の送信 + -**[ご意見の送信]** フォームを使用して、ご提案、問題の報告、または直面している課題を共有してください。 +## コンテキスト編集とライブ デザイン コントロール - -

ご意見の送信

+より簡単な対話のために、AI チャットとデザイン サーフェスの間に深い統合があります。 + +- **コンテキスト ポップアップ**: 任意の UI 要素をクリックして、AI コンテキスト ポップアップを通じて変更できます。 +- **コンポーネント インジケーター**: 選択されているものを常に表示します。 +- **リアルタイム フィードバック**: デザイン エリア処理インジケーターを介したリアルタイム フィードバックにより、生成または更新中に情報を提供し続けます。 + + + +## AI 駆動型の「新しいアプリの作成」ダイアログ + +AI 駆動型の「新しいアプリの作成」ダイアログでプロジェクトを開始します。パーソナライズされたエクスペリエンス、改善されたフィルタリング、発見のためのプロンプト カードを備えた、より豊富なプロンプト ギャラリーを備えています。 + + ## その他のリソース
- [App Builder インターフェイスの概要](../interface-overview.md) -- [単一ページとナビゲーション](../single-page-apps-and-navigation.md) - [App Builder コンポーネント](../indigo-design-app-builder-components.md) -- [Flex レイアウト](../flex-layouts/flex-layouts.md) -- [Desktop アプリの実行方法](../running-desktop-app.md) - [アプリの生成](../generate-app/generate-app-overview.md) -- [Indigo.Design はじめに]({environment:infragisticsBaseUrl}/products/indigo-design/help/getting-started) diff --git a/jp/images/ai/Replace content with AI.gif b/jp/images/ai/Replace content with AI.gif deleted file mode 100644 index 83aef75..0000000 Binary files a/jp/images/ai/Replace content with AI.gif and /dev/null differ diff --git a/jp/images/ai/add-my-profile-icon-1.gif b/jp/images/ai/add-my-profile-icon-1.gif new file mode 100644 index 0000000..3791d8b Binary files /dev/null and b/jp/images/ai/add-my-profile-icon-1.gif differ diff --git a/jp/images/ai/complex-page-example-preview.png b/jp/images/ai/complex-page-example-preview.png deleted file mode 100644 index 484f758..0000000 Binary files a/jp/images/ai/complex-page-example-preview.png and /dev/null differ diff --git a/jp/images/ai/complex-page-example.png b/jp/images/ai/complex-page-example.png deleted file mode 100644 index 98fd00a..0000000 Binary files a/jp/images/ai/complex-page-example.png and /dev/null differ diff --git a/jp/images/ai/content-generation-options.png b/jp/images/ai/content-generation-options.png deleted file mode 100644 index ee392a6..0000000 Binary files a/jp/images/ai/content-generation-options.png and /dev/null differ diff --git a/jp/images/ai/data-source-generation.png b/jp/images/ai/data-source-generation.png deleted file mode 100644 index 59918b9..0000000 Binary files a/jp/images/ai/data-source-generation.png and /dev/null differ diff --git a/jp/images/ai/entry-blog-gif.gif b/jp/images/ai/entry-blog-gif.gif new file mode 100644 index 0000000..d6e2857 Binary files /dev/null and b/jp/images/ai/entry-blog-gif.gif differ diff --git a/jp/images/ai/gallery-view.gif b/jp/images/ai/gallery-view.gif new file mode 100644 index 0000000..eaeb5d0 Binary files /dev/null and b/jp/images/ai/gallery-view.gif differ diff --git a/jp/images/ai/gen-from-image-preview.png b/jp/images/ai/gen-from-image-preview.png deleted file mode 100644 index f95d961..0000000 Binary files a/jp/images/ai/gen-from-image-preview.png and /dev/null differ diff --git a/jp/images/ai/gen-from-image.png b/jp/images/ai/gen-from-image.png deleted file mode 100644 index cc63abe..0000000 Binary files a/jp/images/ai/gen-from-image.png and /dev/null differ diff --git a/jp/images/ai/image-10-1536x729.png b/jp/images/ai/image-10-1536x729.png new file mode 100644 index 0000000..2d0c46c Binary files /dev/null and b/jp/images/ai/image-10-1536x729.png differ diff --git a/jp/images/ai/image-11-1536x729.png b/jp/images/ai/image-11-1536x729.png new file mode 100644 index 0000000..ebbe0b8 Binary files /dev/null and b/jp/images/ai/image-11-1536x729.png differ diff --git a/jp/images/ai/image-13.png b/jp/images/ai/image-13.png new file mode 100644 index 0000000..96ab3cb Binary files /dev/null and b/jp/images/ai/image-13.png differ diff --git a/jp/images/ai/image-15-1536x729.png b/jp/images/ai/image-15-1536x729.png new file mode 100644 index 0000000..68e7b9d Binary files /dev/null and b/jp/images/ai/image-15-1536x729.png differ diff --git a/jp/images/ai/image-16-1536x729.png b/jp/images/ai/image-16-1536x729.png new file mode 100644 index 0000000..781524f Binary files /dev/null and b/jp/images/ai/image-16-1536x729.png differ diff --git a/jp/images/ai/image-17-1536x729.png b/jp/images/ai/image-17-1536x729.png new file mode 100644 index 0000000..8be07c5 Binary files /dev/null and b/jp/images/ai/image-17-1536x729.png differ diff --git a/jp/images/ai/image-9-1536x729.png b/jp/images/ai/image-9-1536x729.png new file mode 100644 index 0000000..08ba004 Binary files /dev/null and b/jp/images/ai/image-9-1536x729.png differ diff --git a/jp/images/ai/image-generation.png b/jp/images/ai/image-generation.png deleted file mode 100644 index 35f2b9e..0000000 Binary files a/jp/images/ai/image-generation.png and /dev/null differ diff --git a/jp/images/ai/login-screen-canvas.png b/jp/images/ai/login-screen-canvas.png deleted file mode 100644 index c7da4a6..0000000 Binary files a/jp/images/ai/login-screen-canvas.png and /dev/null differ diff --git a/jp/images/ai/login-screen-preview-blazor.png b/jp/images/ai/login-screen-preview-blazor.png deleted file mode 100644 index f79b3ad..0000000 Binary files a/jp/images/ai/login-screen-preview-blazor.png and /dev/null differ diff --git a/jp/images/ai/login-screen-preview.png b/jp/images/ai/login-screen-preview.png deleted file mode 100644 index e8c11c3..0000000 Binary files a/jp/images/ai/login-screen-preview.png and /dev/null differ diff --git a/jp/images/ai/login-screen.png b/jp/images/ai/login-screen.png deleted file mode 100644 index 7b88405..0000000 Binary files a/jp/images/ai/login-screen.png and /dev/null differ diff --git a/jp/images/ai/prompt-1.png b/jp/images/ai/prompt-1.png deleted file mode 100644 index 0ad239a..0000000 Binary files a/jp/images/ai/prompt-1.png and /dev/null differ diff --git a/jp/images/ai/prompt-2.png b/jp/images/ai/prompt-2.png deleted file mode 100644 index 0e08314..0000000 Binary files a/jp/images/ai/prompt-2.png and /dev/null differ diff --git a/jp/images/ai/send-feedback.png b/jp/images/ai/send-feedback.png deleted file mode 100644 index b49e541..0000000 Binary files a/jp/images/ai/send-feedback.png and /dev/null differ diff --git a/jp/images/ai/speech-to-text.gif b/jp/images/ai/speech-to-text.gif new file mode 100644 index 0000000..001a5f8 Binary files /dev/null and b/jp/images/ai/speech-to-text.gif differ diff --git a/jp/images/ai/theme-generation.png b/jp/images/ai/theme-generation.png deleted file mode 100644 index 5979bab..0000000 Binary files a/jp/images/ai/theme-generation.png and /dev/null differ diff --git a/jp/using-data-in-your-app/api-project-query-builder-support.md b/jp/using-data-in-your-app/api-project-query-builder-support.md index 0892d06..16def02 100644 --- a/jp/using-data-in-your-app/api-project-query-builder-support.md +++ b/jp/using-data-in-your-app/api-project-query-builder-support.md @@ -11,239 +11,476 @@ _language: ja このガイドでは、ユーザー定義のクエリを有効にするために、API プロジェクトにクエリ ビルダー モデルとユーティリティを実装する方法について説明します。実装には、コントローラーの作成、クエリ ビルダー モデルの定義、およびこれらのクエリから SQL ステートメントを実行および生成するためのユーティリティの追加が含まれます。結果として得られるカスタマイズにより、ユーザーはサブクエリのサポート、フィルタリング、論理演算子、フィールド選択を使用して複雑なクエリを構築し、データ ソースに対して効率的に実行できるようになります。 -この実装はすでに [NorthwindAPI REST API](https://github.com/IgniteUI/NorthwindAPI/tree/main/NorthwindCRUD/QueryBuilder) プロジェクトの一部になっています。これらは NorthwindAPI QueryBuilderController と NorthwindAPI QueryBuilder モデルの例です: [NorthwindAPI QueryBuilderController](https://github.com/IgniteUI/NorthwindAPI/blob/main/NorthwindCRUD/Controllers/QueryBuilderController.cs) と [NorthwindAPI QueryBuilder モデル](https://github.com/IgniteUI/NorthwindAPI/tree/main/NorthwindCRUD/QueryBuilder)。 +## 実装オプション -[クエリ ビルダーの使用方法のステップ バイ ステップ ガイド](query-builder-step-by-step-guide.md)のトピックでは、クエリ ビルダー変数とコンポーネントを [App Builder プレビュー版環境](https://preview.appbuilder.dev/)の一部として使用する方法について詳しく説明します。 +API プロジェクトでクエリ ビルダー サポートを実装するには、2 つの方法があります。 -## 前提条件 +| 方法 | 最適な用途 | 作業レベル | +|----------|----------|--------------| +| **NuGet パッケージ** (`Infragistics.QueryBuilder.Executor`) | 迅速な統合、標準的なユース ケース | 低 | +| **手動での実装** | 完全なカスタマイズ、複雑な要件 | 中~高 | + +## オプション 1: Infragistics.QueryBuilder.Executor NuGet パッケージの使用 (推奨) + +`Infragistics.QueryBuilder.Executor` パッケージは、最小限の構成で既存の API プロジェクトに直接組み込むことができる、すぐに使用できるクラス、条件、およびメソッドを提供します。 + +[![NuGet](https://img.shields.io/nuget/v/Infragistics.QueryBuilder.Executor.svg)](https://www.nuget.org/packages/Infragistics.QueryBuilder.Executor/) + +### 前提条件 + +- .NET 8 または .NET 9 +- Microsoft.EntityFrameworkCore +- AutoMapper +- 既存の ASP.NET Core API プロジェクト + +### 手順 1: パッケージのインストール + +```bash +dotnet add package Infragistics.QueryBuilder.Executor +``` + +### 手順 2: サービスの構成 + +`Program.cs` または `Startup.cs` で、DbContext と結果 DTO を使用して QueryBuilder サービスを登録します。 + +```csharp +// Program.cs +builder.Services.AddQueryBuilder(); + +// Required for SwaggerUI compatibility +builder.Services.AddControllers().AddNewtonsoftJson(o => + o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore); +``` + +### 手順 3: クエリ エンドポイントの公開 + +クエリ ビルダー機能を公開するためにエンドポイント ルーティングを構成します。 + +```csharp +app.UseEndpoints(endpoints => +{ + endpoints.UseQueryBuilder("/api/query"); +}); +``` + +### 手順 4: クエリの送信 + +API がクエリ ペイロードを受け入れる準備が整いました。以下はリクエストの例です。 + +```json +{ + "Entity": "Users", + "ReturnFields": ["Id", "Name", "Email"], + "Operator": "And", + "FilteringOperands": [ + { + "FieldName": "IsActive", + "Condition": { "Name": "equals" }, + "SearchVal": true + }, + { + "FieldName": "CreatedDate", + "Condition": { "Name": "after" }, + "SearchVal": "2024-01-01" + } + ] +} +``` + +### 手順 5: SQL の生成 (オプション) + +診断や分析のために、クエリ モデルから SQL を生成できます。 + +```csharp +var sql = SqlGenerator.GenerateSql(query); +Console.WriteLine(sql); +// Output: SELECT Id, Name, Email FROM Users WHERE IsActive = 1 AND CreatedDate > '2024-01-01' +``` + +## オプション 2: 手動での実装 + +完全なカスタマイズや複雑なエンティティ マッピングが必要なプロジェクトでは、クエリ ビルダーを手動で実装できます。実装は [NorthwindAPI REST API](https://github.com/IgniteUI/NorthwindAPI/tree/main/NorthwindCRUD/QueryBuilder) プロジェクトで示されています。 + +### 前提条件 - .NET Core または .NET API プロジェクト。 - LINQ、Entity Framework、またはその他の ORM を使用したデータ クエリの基礎知識。 - C# および ASP.NET Core コントローラーの基本的な理解。 -## 手順 1: QueryBuilderController の作成 +### 手順 1: QueryBuilderController の作成 -QueryBuilderController は、クエリ リクエストを処理するためのエントリ ポイントとして機能します。クライアントから Query オブジェクトを受け取り、QueryExecutor または SqlGenerator を使用して処理し、結果を返します。 +QueryBuilderController は、クエリ リクエストを処理するためのエントリ ポイントとして機能します。クライアントから Query オブジェクトを受け取り、QueryExecutor を使用して処理し、結果を返します。 -### 実装 +Controllers ディレクトリに `QueryBuilderController.cs` という名前のファイルを作成します。 -Controllers ディレクトリに QueryBuilderController.cs という名前のファイルを作成します。 +```csharp +[ApiController] +[Route("[controller]")] +public class QueryBuilderController : ControllerBase +{ + private readonly DataContext dataContext; + private readonly IMapper mapper; + private readonly ILogger logger; + + public QueryBuilderController(DataContext dataContext, IMapper mapper, ILogger logger) + { + this.dataContext = dataContext; + this.mapper = mapper; + this.logger = logger; + } -``` [HttpPost("ExecuteQuery")] -    [Consumes("application/json")] -    [Produces("application/json")] -    public ActionResult ExecuteQuery(Query query) -    { -        var sanitizedEntity = query.Entity.Replace("\r", string.Empty).Replace("\n", string.Empty); -        logger.LogInformation("Executing query for entity: {Entity}", sanitizedEntity); -        var t = query.Entity.ToLower(CultureInfo.InvariantCulture); -        return Ok(new Dictionary -        { -            { -                t, -                t switch -                { -                    "addresses" => dataContext.Addresses.Run(query, mapper), -                    "categories" => dataContext.Categories.Run(query, mapper), -                    "products" => dataContext.Products.Run(query, mapper), -                    "regions" => dataContext.Regions.Run(query, mapper), -                    "territories" => dataContext.Territories.Run(query, mapper), -                    "employees" => dataContext.Employees.Run(query, mapper), -                    "customers" => dataContext.Customers.Run(query, mapper), -                    "orders" => dataContext.Orders.Run(query, mapper), -                    "orderdetails" => dataContext.OrderDetails.Run(query, mapper), -                    "shippers" => dataContext.Shippers.Run(query, mapper), -                    "suppliers" => dataContext.Suppliers.Run(query, mapper), -                    _ => throw new InvalidOperationException($"Unknown entity {t}"), -                } -            }, -        }); -    } + [Consumes("application/json")] + [Produces("application/json")] + public ActionResult ExecuteQuery(Query query) + { + var sanitizedEntity = query.Entity.Replace("\r", string.Empty).Replace("\n", string.Empty); + logger.LogInformation("Executing query for entity: {Entity}", sanitizedEntity); + var t = query.Entity.ToLower(CultureInfo.InvariantCulture); + return Ok(new Dictionary + { + { + t, + t switch + { + "addresses" => dataContext.Addresses.Run(query, mapper), + "categories" => dataContext.Categories.Run(query, mapper), + "products" => dataContext.Products.Run(query, mapper), + "regions" => dataContext.Regions. Run(query, mapper), + "territories" => dataContext.Territories. Run(query, mapper), + "employees" => dataContext.Employees. Run(query, mapper), + "customers" => dataContext.Customers.Run(query, mapper), + "orders" => dataContext.Orders.Run(query, mapper), + "orderdetails" => dataContext.OrderDetails.Run(query, mapper), + "shippers" => dataContext.Shippers.Run(query, mapper), + "suppliers" => dataContext.Suppliers.Run(query, mapper), + _ => throw new InvalidOperationException($"Unknown entity {t}"), + } + }, + }); + } +} ``` -- 目的: POST リクエストで Query オブジェクトを受け取り、QueryExecutor に処理を委ねます。 -- 依存性の注入: QueryExecutor を注入してクエリの処理を実行します (DI コンテナーで設定)。 - 完全な例については、[NorthwindAPI QueryBuilderController](https://github.com/IgniteUI/NorthwindAPI/blob/main/NorthwindCRUD/Controllers/QueryBuilderController.cs) を参照してください。 +### 手順 2: クエリ ビルダー モデルの定義 -## 手順 2: クエリ ビルダー モデルの定義 - -クエリ ビルダーは、クエリ構造を表すためのモデル郡に依存します。これらを QueryBuilder ディレクトリまたは名前空間 (例: YourNamespace.QueryBuilder) に配置します。 +クエリ ビルダーは、クエリ構造を表すためのモデル郡に依存します。これらを `QueryBuilder` ディレクトリまたは名前空間に配置します。 -### FilterType 列挙型 +#### FilterType 列挙型 フィルターを組み合わせるための論理演算子を定義します。 -``` +```csharp public enum FilterType { -    And = 0, -    Or = 1, + And = 0, + Or = 1, } ``` -- And: フィルターを論理 AND で結合します。 -- Or: フィルターを論理 OR で結合します。 - - -### Query クラス +#### Query クラス クエリ全体の構造を表します。 -``` +```csharp public class Query { -    public string Entity { get; set; } -    public string[] ReturnFields { get; set; } -    public FilterType Operator { get; set; } -    public QueryFilter[] FilteringOperands { get; set; } + public string Entity { get; set; } + public string[] ReturnFields { get; set; } + public FilterType Operator { get; set; } + public QueryFilter[] FilteringOperands { get; set; } } ``` -- Entity: クエリの対象となるエンティティ/テーブル (例: "Products")。 -- ReturnFields: 結果に含めるフィールド (例: ["Name", "Price"]、またはすべてを表す ["*"])。 -- Operator: フィルターを組み合わせるための論理演算子 (And または Or)。 -- FilteringOperands: 条件を定義する QueryFilter オブジェクトの配列。 +| プロパティ | 説明 | +|----------|-------------| +| `Entity` | クエリの対象となるエンティティ/テーブル (例: "Products")。 | +| `ReturnFields` | 結果に含めるフィールド (例: `["Name", "Price"]`、またはすべてを表す `["*"]`)。 | +| `Operator` | フィルターを組み合わせるための論理演算子 (`And` または `Or`)。 | +| `FilteringOperands` | 条件を定義する QueryFilter オブジェクトの配列。 | -### QueryFilter クラス +#### QueryFilter クラス 個別のフィルタリング条件を表します。 -``` +```csharp public class QueryFilter { -    // Basic condition -    public string? FieldName { get; set; } -    public bool? IgnoreCase { get; set; } -    public QueryFilterCondition? Condition { get; set; } -    public object? SearchVal { get; set; } -    public Query? SearchTree { get; set; } -    // And/Or -    public FilterType? Operator { get; set; } -    public QueryFilter[] FilteringOperands { get; set; } + // Basic condition + public string? FieldName { get; set; } + public bool? IgnoreCase { get; set; } + public QueryFilterCondition? Condition { get; set; } + public object? SearchVal { get; set; } + public Query? SearchTree { get; set; } + // And/Or + public FilterType? Operator { get; set; } + public QueryFilter[] FilteringOperands { get; set; } } ``` -- FieldName: フィルタリングするフィールド (例: "Price")。 -- IgnoreCase: フィルターが大文字と小文字を区別するかどうか。 -- Condition: 比較タイプ (例: "Equals"、"GreaterThan")。 -- SearchVal: 比較する値 (例: 100)。 -- SearchTree: サブクエリのネストされたクエリ。 -- Operator: 複合条件の論理演算子。 -- FilteringOperands: ネストされたフィルターまたは複合フィルターの配列。 - -### QueryFilterCondition クラス +#### QueryFilterCondition クラス 使用可能なフィルタリング条件を定義します。 -``` +```csharp public class QueryFilterCondition { -    public string Name { get; set; } -    public bool IsUnary { get; set; } -    public string IconName { get; set; } + public string Name { get; set; } + public bool IsUnary { get; set; } + public string IconName { get; set; } } ``` -- Name: 条件識別子 (例: "Equals"、"Contains")。 -- IsUnary: 単一オペランド条件の場合は True です (例: "IsNull")。 -- IconName: UI アイコン識別子 (オプション)。 - 詳細な実装は、[NorthwindAPI QueryBuilder モデル](https://github.com/IgniteUI/NorthwindAPI/tree/main/NorthwindCRUD/QueryBuilder)を参照してください。 -## 手順 3: QueryExecutor の実装 +### 手順 3: QueryExecutor の実装 -QueryExecutor クラスは、Query オブジェクトを処理し、 LINQ 式に変換して IQueryable データ ソースに対して実行します。 +QueryExecutor クラスは、Query オブジェクトを処理し、LINQ 式に変換して IQueryable データ ソースに対して実行します。 -### 実装 - -QueryExecutor.cs という名前の新しいファイルを作成します。 +```csharp +private static Expression BuildConditionExpression( + DataContext db, + IQueryable source, + QueryFilter filter, + ParameterExpression parameter) +{ + if (filter. FieldName is not null && filter.Condition is not null) + { + var property = source.ElementType.GetProperty( + filter.FieldName, + BindingFlags. IgnoreCase | BindingFlags.Public | BindingFlags. Instance) + ?? throw new InvalidOperationException($"Property '{filter.FieldName}' not found"); + + var field = Expression.Property(parameter, property); + var targetType = property.PropertyType; + var searchValue = GetSearchValue(filter.SearchVal, targetType); + + Expression condition = filter.Condition.Name switch + { + "null" => Expression.Equal(field, Expression.Constant(null)), + "notNull" => Expression.NotEqual(field, Expression.Constant(null)), + "empty" => Expression.Equal(field, Expression.Constant(string.Empty)), + "notEmpty" => Expression.NotEqual(field, Expression.Constant(string.Empty)), + "equals" => Expression.Equal(field, searchValue), + "doesNotEqual" => Expression.NotEqual(field, searchValue), + "inQuery" => BuildInExpression(db, filter.SearchTree, field), + "notInQuery" => Expression.Not(BuildInExpression(db, filter.SearchTree, field)), + "contains" => CallContains(field, searchValue), + "doesNotContain" => Expression.Not(CallContains(field, searchValue)), + "startsWith" => CallStartsWith(field, searchValue), + "endsWith" => CallEndsWith(field, searchValue), + "greaterThan" => Expression.GreaterThan(field, searchValue), + "lessThan" => Expression.LessThan(field, searchValue), + "greaterThanOrEqualTo" => Expression.GreaterThanOrEqual(field, searchValue), + "lessThanOrEqualTo" => Expression.LessThanOrEqual(field, searchValue), + "before" => Expression.LessThan(field, searchValue), + "after" => Expression.GreaterThan(field, searchValue), + "today" => BuildTodayExpression(field), + "yesterday" => BuildYesterdayExpression(field), + "thisMonth" => BuildThisMonthExpression(field), + "lastMonth" => BuildLastMonthExpression(field), + "nextMonth" => BuildNextMonthExpression(field), + "thisYear" => BuildThisYearExpression(field), + "lastYear" => BuildLastYearExpression(field), + "nextYear" => BuildNextYearExpression(field), + "true" => Expression.Equal(field, Expression.Constant(true)), + "false" => Expression.Equal(field, Expression.Constant(false)), + _ => throw new NotImplementedException($"Condition not implemented: {filter.Condition. Name}"), + }; + + return condition; + } + else + { + // Handle nested filter groups + var subexpressions = filter.FilteringOperands? + .Select(f => BuildConditionExpression(db, source, f, parameter)) + .ToArray(); + + if (subexpressions == null || ! subexpressions.Any()) + return Expression. Constant(true); + + return filter.Operator == FilterType.And + ? subexpressions. Aggregate(Expression.AndAlso) + : subexpressions.Aggregate(Expression.OrElse); + } +} +``` +## サポートされているフィルター条件 + +どちらの実装オプションも、Angular クエリ ビルダー コンポーネント (`IgxQueryBuilderComponent`) に対応する以下のフィルター条件をサポートしています。 + +### 文字列の条件 + +| 条件 | 説明 | +|-----------|-------------| +| `contains` | フィールドに検索値が含まれる | +| `doesNotContain` | フィールドに検索値が含まれない | +| `startsWith` | フィールドが検索値で始まる | +| `endsWith` | フィールドが検索値で終わる | +| `equals` | フィールドが検索値と等しい | +| `doesNotEqual` | フィールドが検索値と等しくない | +| `empty` | フィールドが空 | +| `notEmpty` | フィールドが空でない | +| `null` | フィールドが null | +| `notNull` | フィールドが null でない | + +### 数値の条件 + +| 条件 | 説明 | +|-----------|-------------| +| `equals` | フィールドが検索値と等しい | +| `doesNotEqual` | フィールドが検索値と等しくない | +| `greaterThan` | フィールドが検索値より大きい | +| `lessThan` | フィールドが検索値より小さい | +| `greaterThanOrEqualTo` | フィールドが検索値より大きい | +| `lessThanOrEqualTo` | フィールドが検索値より小さい | +| `empty` | フィールドが空/ゼロ | +| `notEmpty` | フィールドが空/ゼロでない | +| `null` | フィールドが null | +| `notNull` | フィールドが null でない | + +### 日付/時刻の条件 + +| 条件 | 説明 | +|-----------|-------------| +| `equals` | フィールドが検索値と等しい | +| `doesNotEqual` | フィールドが検索値と等しくない | +| `before` | フィールドが検索値より前である | +| `after` | フィールドが検索値より後である | +| `today` | フィールドが今日の日付と一致する | +| `yesterday` | フィールドが昨日の日付と一致する | +| `thisMonth` | フィールドが今月内である | +| `lastMonth` | フィールドが先月内である | +| `nextMonth` | フィールドが来月内である | +| `thisYear` | フィールドが今年内である | +| `lastYear` | フィールドが昨年内である | +| `nextYear` | フィールドが来年内である | +| `null` | フィールドが null | +| `notNull` | フィールドが null でない | + +### ブール値の条件 + +| 条件 | 説明 | +|-----------|-------------| +| `true` | フィールドが true である | +| `false` | フィールドが false である | +| `null` | フィールドが null | +| `notNull` | フィールドが null でない | + +### サブクエリ条件 + +| 条件 | 説明 | +|-----------|-------------| +| `inQuery` | フィールド値がサブクエリ結果に存在する | +| `notInQuery` | フィールド値がサブクエリ結果に存在しない | + + +## Angular フロントエンドとの統合 + +クエリ ビルダー API は、**Ignite UI for Angular クエリ ビルダー コンポーネント** (`IgxQueryBuilderComponent`) とシームレスに連携するように設計されています。このコンポーネントは、期待される API ペイロード形式と一致するクエリ構造を生成します。 + +### 主要な Angular コンポーネント + +`IgniteUI/igniteui-angular` リポジトリから: + +```typescript +import { + FilteringExpressionsTree, + FilteringLogic, + IgxQueryBuilderComponent, + IExpressionTree, + IgxNumberFilteringOperand, + IgxStringFilteringOperand, + IgxBooleanFilteringOperand, + IgxDateFilteringOperand, + IgxTimeFilteringOperand, + IgxDateTimeFilteringOperand +} from 'igniteui-angular'; ``` -... -private static Expression BuildConditionExpression(DataContext db, IQueryable source, QueryFilter filter, ParameterExpression parameter) -    { -        if (filter.FieldName is not null && filter.Condition is not null) -        { -            var property = source.ElementType.GetProperty(filter.FieldName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance) -                                 ?? throw new InvalidOperationException($"Property '{filter.FieldName}' not found on type '{source.ElementType}'"); -            var field = Expression.Property(parameter, property); -            var targetType = property.PropertyType; -            var searchValue = GetSearchValue(filter.SearchVal, targetType); -            var emptyValue = GetEmptyValue(targetType); -            var today = DateTime.Now.Date; -            Expression condition = filter.Condition.Name switch -            { -                "null"                  => targetType.IsNullableType() ? Expression.Equal(field, Expression.Constant(targetType.GetDefaultValue())) : Expression.Constant(false), -                "notNull"               => targetType.IsNullableType() ? Expression.NotEqual(field, Expression.Constant(targetType.GetDefaultValue())) : Expression.Constant(true), -                "empty"                 => Expression.Or(Expression.Equal(field, emptyValue), targetType.IsNullableType() ? Expression.Equal(field, Expression.Constant(targetType.GetDefaultValue())) : Expression.Constant(false)), -                "notEmpty"              => Expression.And(Expression.NotEqual(field, emptyValue), targetType.IsNullableType() ? Expression.NotEqual(field, Expression.Constant(targetType.GetDefaultValue())) : Expression.Constant(true)), -                "equals"                => Expression.Equal(field, searchValue), -                "doesNotEqual"          => Expression.NotEqual(field, searchValue), -                "inQuery"               => BuildInExpression(db, filter.SearchTree, field), -                "notInQuery"            => Expression.Not(BuildInExpression(db, filter.SearchTree, field)), -                "contains"              => CallContains(field, searchValue), -                "doesNotContain"        => Expression.Not(CallContains(field, searchValue)), -                "startsWith"            => CallStartsWith(field, searchValue), -                "endsWith"              => CallEndsWith(field, searchValue), -                "greaterThan"           => Expression.GreaterThan(field, searchValue), -                "lessThan"              => Expression.LessThan(field, searchValue), -                "greaterThanOrEqualTo"  => Expression.GreaterThanOrEqual(field, searchValue), -                "lessThanOrEqualTo"     => Expression.LessThanOrEqual(field, searchValue), -                "before"                => Expression.LessThan(CallCompare(field, searchValue), Expression.Constant(0)), -                "after"                 => Expression.GreaterThan(CallCompare(field, searchValue), Expression.Constant(0)), -                "today"                 => CallStartsWith(field, today.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)), -                "yesterday"             => CallStartsWith(field, today.AddDays(-1).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)), -                "thisMonth"             => CallStartsWith(field, today.ToString("yyyy-MM", CultureInfo.InvariantCulture)), -                "lastMonth"             => CallStartsWith(field, today.AddMonths(-1).ToString("yyyy-MM", CultureInfo.InvariantCulture)), -                "nextMonth"             => CallStartsWith(field, today.AddMonths(1).ToString("yyyy-MM", CultureInfo.InvariantCulture)), -                "thisYear"              => CallStartsWith(field, today.ToString("yyyy", CultureInfo.InvariantCulture)), -                "lastYear"              => CallStartsWith(field, today.AddYears(-1).ToString("yyyy", CultureInfo.InvariantCulture)), -                "nextYear"              => CallStartsWith(field, today.AddYears(1).ToString("yyyy", CultureInfo.InvariantCulture)), -                "at"                    => Expression.Equal(field, searchValue), -                "not_at"                => Expression.NotEqual(field, searchValue), -                "at_before"             => Expression.LessThan(CallCompare(field, searchValue), Expression.Constant(0)), -                "at_after"              => Expression.GreaterThan(CallCompare(field, searchValue), Expression.Constant(0)), -                "all"                   => Expression.Constant(true), -                "true"                  => Expression.Equal(field, Expression.Constant(true)), -                "false"                 => Expression.Equal(field, Expression.Constant(false)), -                _                       => throw new NotImplementedException("Not implemented"), -            }; - -            if (filter.IgnoreCase == true && field.Type == typeof(string)) -            { -                // TODO: Implement case-insensitive comparison -            } - -            return condition; -        } -        else -        { -            var subexpressions = filter.FilteringOperands?.Select(f => BuildConditionExpression(db, source, f, parameter)).ToArray(); -            if (subexpressions == null || !subexpressions.Any()) -            { -                return Expression.Constant(true); -            } - -            return filter.Operator == FilterType.And -                ? subexpressions.Aggregate(Expression.AndAlso) -                : subexpressions.Aggregate(Expression.OrElse); -        } -    } -... + +### 例: クエリ式ツリーの作成 + +```typescript +// エンティティとフィールドの定義 +const entities = [ + { + name: 'Products', + fields: [ + { field: 'productId', dataType: 'number' }, + { field: 'productName', dataType: 'string' }, + { field: 'unitPrice', dataType: 'number' }, + { field: 'discontinued', dataType: 'boolean' }, + { field: 'categoryId', dataType: 'number' } + ] + }, + { + name: 'OrderDetails', + fields: [ + { field: 'productId', dataType: 'number' }, + { field: 'quantity', dataType: 'number' }, + { field: 'discount', dataType: 'number' } + ] + } +]; + +// サブクエリを含む複雑なクエリの構築 +const innerTree = new FilteringExpressionsTree( + FilteringLogic. And, + undefined, + 'OrderDetails', + ['productId'] +); + +innerTree.filteringOperands. push({ + fieldName: 'quantity', + condition: IgxNumberFilteringOperand. instance().condition('greaterThanOrEqualTo'), + conditionName: 'greaterThanOrEqualTo', + searchVal: 10 +}); + +const mainTree = new FilteringExpressionsTree( + FilteringLogic.And, + undefined, + 'Products', + ['*'] +); + +mainTree.filteringOperands.push({ + fieldName: 'productId', + condition: IgxStringFilteringOperand.instance().condition('inQuery'), + conditionName: 'inQuery', + searchTree: innerTree +}); + +mainTree.filteringOperands.push({ + fieldName: 'discontinued', + condition: IgxBooleanFilteringOperand.instance().condition('false'), + conditionName: 'false' +}); ``` -- SELECT 句: フィールド選択を構築するか、デフォルトで * に設定します。 -- WHERE 句: フィルター条件を AND/OR 演算子で組み合わせます。 -- 注: 特定の条件をサポートするには、BuildCondition を実装します (例: "Equals" → =, "Contains" → LIKE)。 +### クエリ ビルダー コンポーネントの使用 + +```html + + + + +``` -## 使用例の結果 +## 例: サブクエリを含む複雑なクエリ -複雑なクエリのサンプル +### クエリ ペイロード -``` +```json { "filteringOperands": [ { @@ -321,9 +558,9 @@ private static Expression BuildConditionExpression(DataContext db, IQue } ``` -**SQL 出力** +### 生成された SQL 出力 -``` +```sql SELECT * FROM products WHERE categoryId = {{selectedCategory}} @@ -335,27 +572,47 @@ AND productId IN ( ) ``` -リクエスト本文に filteringExpressionTree を含む POST リクエスト +### API エンドポイント ``` -https://data-northwind.appbuilder.dev/QueryBuilder/ExecuteQuery +POST https://data-northwind.appbuilder.dev/QueryBuilder/ExecuteQuery +Content-Type: application/json +``` + +## ローカライゼーション サポート + +Angular クエリ ビルダー コンポーネントには、フィルター条件ラベル用の組み込みローカライゼーション サポートが含まれています。`igniteui-angular` リポジトリは、以下を含む複数の言語のリソース文字列を提供しています。 + +- 英語 (EN) - デフォルト +- フランス語 (FR) +- ドイツ語 (DE) +- スペイン語 (ES) +- イタリア語 (IT) +- ポルトガル語 (PT) +- ポーランド語 (PL) +- スウェーデン語 (SV) +- その他 + +リソース文字列の例: + +```typescript +export const QueryBuilderResourceStringsEN: IQueryBuilderResourceStrings = { + igx_query_builder_filter_contains: 'Contains', + igx_query_builder_filter_doesNotContain: 'Does Not Contain', + igx_query_builder_filter_startsWith: 'Starts With', + igx_query_builder_filter_endsWith: 'Ends With', + igx_query_builder_filter_equals: 'Equals', + igx_query_builder_filter_doesNotEqual: 'Does Not Equal', + igx_query_builder_filter_greaterThan: 'Greater Than', + igx_query_builder_filter_lessThan: 'Less Than', + // ... more strings +}; ``` ## その他の参考資料 +- [Infragistics. QueryBuilder. Executor NuGet パッケージ](https://www.nuget.org/packages/Infragistics.QueryBuilder.Executor/) - [NorthwindAPI QueryBuilderController](https://github.com/IgniteUI/NorthwindAPI/blob/main/NorthwindCRUD/Controllers/QueryBuilderController.cs) - [NorthwindAPI QueryBuilder モデル](https://github.com/IgniteUI/NorthwindAPI/tree/main/NorthwindCRUD/QueryBuilder) - -## その他のリソース - -
- +- [Ignite UI for Angular Query Builder コンポーネント](https://github.com/IgniteUI/igniteui-angular/tree/master/projects/igniteui-angular/query-builder) - [クエリ ビルダーの使用方法のステップ バイス テップ ガイド](query-builder-step-by-step-guide.md) -- [App Builder コンポーネント](../indigo-design-app-builder-components.md) -- [App Builder インターフェイスの概要](../interface-overview.md) -- [フォーム ビルダー](form-builder.md) -- [グリッド リモート ページング](grid-remote-paging.md) -- [CRUD 操作](crud-operations.md) -- [リモート データ操作](remote-data-operations.md) -- [Flex レイアウト](../flex-layouts/flex-layouts.md) -- [Desktop アプリの実行方法](../running-desktop-app.md)