From 5b2298a294131bc668310a4689a8488db8e69042 Mon Sep 17 00:00:00 2001 From: olprod Date: Wed, 1 Aug 2018 12:30:07 +0000 Subject: [PATCH] commit translated contents --- docs/core/get-started.md | 104 ++++-- docs/core/tools/dotnet-build-server.md | 24 +- docs/core/versions/selection.md | 112 ++++++ .../language-reference/keywords/global.md | 49 +-- .../keywords/group-clause.md | 179 +++++----- .../language-reference/keywords/readonly.md | 141 +++++--- .../csharp/language-reference/keywords/ref.md | 73 ++-- .../language-reference/keywords/volatile.md | 32 +- .../preprocessor-define.md | 30 +- .../preprocessor-undef.md | 28 +- docs/csharp/linq/create-a-nested-group.md | 41 +-- ...ly-specify-predicate-filters-at-runtime.md | 132 +++---- docs/csharp/linq/group-query-results.md | 156 +++++---- .../linq/group-results-by-contiguous-keys.md | 99 +++--- .../handle-exceptions-in-query-expressions.md | 62 ++-- ...handle-null-values-in-query-expressions.md | 53 +-- .../linq/join-by-using-composite-keys.md | 76 ++-- docs/csharp/linq/linq-in-csharp.md | 79 +++-- .../order-the-results-of-a-join-clause.md | 45 +-- ...form-a-subquery-on-a-grouping-operation.md | 41 +-- .../linq/perform-custom-join-operations.md | 83 ++--- docs/csharp/linq/perform-grouped-joins.md | 76 ++-- docs/csharp/linq/perform-inner-joins.md | 142 ++++---- docs/csharp/linq/perform-left-outer-joins.md | 62 ++-- .../linq/query-a-collection-of-objects.md | 38 +- docs/csharp/linq/query-expression-basics.md | 330 +++++++++--------- docs/csharp/linq/write-linq-queries.md | 169 +++++---- .../arrays/passing-arrays-as-arguments.md | 122 +++---- .../classes-and-structs/local-functions.md | 24 +- .../concepts/async/async-return-types.md | 24 +- ...urn-values-for-multithreaded-procedures.md | 127 +++++++ .../how-to-catch-a-non-cls-exception.md | 79 ++--- .../expressions.md | 29 +- .../types/using-type-dynamic.md | 31 +- docs/csharp/quick-starts/list-collection.yml | 12 +- docs/csharp/tutorials/inheritance.md | 65 ++-- .../framework/install/dotnet-35-windows-10.md | 25 +- .../tutorials/iris-clustering.md | 218 ++++++++++++ docs/machine-learning/tutorials/taxi-fare.md | 12 +- ...nt-the-event-based-asynchronous-pattern.md | 39 ++- ...rt-the-event-based-asynchronous-pattern.md | 52 +-- docs/standard/guidance-architecture.md | 30 +- ...m-http-call-retries-exponential-backoff.md | 122 +++++++ .../handle-partial-failure.md | 26 +- .../implement-circuit-breaker-pattern.md | 221 ++++-------- ...-call-retries-exponential-backoff-polly.md | 203 ++++------- ...t-entity-framework-core-sql-connections.md | 34 +- .../implement-retries-exponential-backoff.md | 24 +- .../partial-failure-strategies.md | 22 +- ...ry-to-implement-resilient-http-requests.md | 168 +++++++++ ...infrastructure-persistence-layer-design.md | 119 ++++--- .../architectural-principles.md | 53 ++- ...ng-recommendations-for-asp-net-web-apps.md | 114 +++--- ...en-traditional-web-and-single-page-apps.md | 53 ++- .../common-client-side-web-technologies.md | 52 ++- .../common-web-application-architectures.md | 211 +++++++---- .../develop-asp-net-core-mvc-apps.md | 165 ++++----- .../development-process-for-azure.md | 33 +- ...modern-web-applications-characteristics.md | 38 +- .../test-asp-net-core-mvc-apps.md | 208 +++++++---- .../work-with-data-in-asp-net-core-apps.md | 105 +++--- docs/standard/threading/autoresetevent.md | 31 +- .../threading-objects-and-features.md | 44 +-- docs/standard/threading/timers.md | 91 +++-- includes/topic-appliesto-net-core-21plus.md | 1 + includes/topic-appliesto-net-core-2plus.md | 2 +- 66 files changed, 3190 insertions(+), 2295 deletions(-) create mode 100644 docs/core/versions/selection.md create mode 100644 docs/csharp/programming-guide/concepts/threading/parameters-and-return-values-for-multithreaded-procedures.md create mode 100644 docs/machine-learning/tutorials/iris-clustering.md create mode 100644 docs/standard/microservices-architecture/implement-resilient-applications/explore-custom-http-call-retries-exponential-backoff.md create mode 100644 docs/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests.md create mode 100644 includes/topic-appliesto-net-core-21plus.md diff --git a/docs/core/get-started.md b/docs/core/get-started.md index 16d0f431b2f..7c6427684cd 100644 --- a/docs/core/get-started.md +++ b/docs/core/get-started.md @@ -1,57 +1,87 @@ --- -title: .NET Core の概要 -description: Windows、Linux、macOS で .NET Core アプリケーションをビルドする方法を学習するためのリソースを示します。 -author: johalex -ms.author: johalex -ms.date: 09/14/2017 -ms.openlocfilehash: 7e70cd4ba9891403f6b5890aa585dafb77c76898 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33212951" +title: .NET Core の概要 +description: Windows、Linux、macOS で .NET Core アプリケーションをビルドする方法を学習するためのリソースを示します。 +author: thraka +ms.author: adegeo +ms.date: 06/27/2018 +ms.openlocfilehash: fa5deb46b64e1a09c9ad6582486a993a24336b42 +ms.sourcegitcommit: 702d5ffc6e733b6c4ded85bf1c92e2293638ee9a +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/04/2018 +ms.locfileid: "37792401" --- # .NET Core の概要 -.NET Core は、[Windows](#windows)、[Linux](#linux)、および [macOS / OS X](#os-x--macos) で実行されます。 +この記事では、.NET Core の概要について説明します。 .NET Core は、Windows、Linux、および macOS にインストールすることができます。 任意のテキスト エディターでコーディングし、クロスプラットフォーム ライブラリとアプリケーションを作成できます。 -## Windows +.NET Core が何であるかや、他の .NET テクノロジとどのように関連しているのかがわからない場合は、まず、[.NET の概要](https://www.microsoft.com/net/learn/what-is-dotnet)を確認してください。 簡単に言うと、.NET Core は .NET のオープンソースのクロスプラットフォーム実装です。 -[Windows](https://www.microsoft.com/net/core#windows) に .NET Core をインストールします。 +## アプリケーションの作成 -次のステップ バイ ステップのチュートリアルに従って、.NET Core アプリの開発を開始できます。 +まず、ご利用のコンピューターで [NET Core SDK](https://www.microsoft.com/net/download/) をダウンロードしてインストールします。 -* [Visual Studio 2017 での .NET Core を使用した C# Hello World アプリケーションの構築](./tutorials/with-visual-studio.md) - C# および Visual Studio 2017 を使用し、単純な .NET Core コンソール アプリケーションを構築、デバッグ、公開する方法について説明します。 -* [C# および Visual Studio 2017 の .NET Core を使用したクラス ライブラリの構築](./tutorials/library-with-visual-studio.md) - Visual Studio 2017 を利用し、C# で記述されたクラス ライブラリをビルドする方法について説明します。 -* [Visual Studio 2017 での .NET Core を使用した Visual Basic Hello World アプリケーションの構築](./tutorials/vb-with-visual-studio.md) - Visual Basic および Visual Studio 2017 を使用し、単純な .NET Core コンソール アプリケーションを構築、デバッグ、公開する方法について説明します。 -* [Visual Basic および Visual Studio 2017 の .NET Core を使用したクラス ライブラリの構築](./tutorials/vb-library-with-visual-studio.md) - Visual Studio 2017 を利用し、Visual Basic で記述されたクラス ライブラリをビルドする方法について説明します。 -* [Windows で C# および .NET Core を使用した Visual Studio Code の概要](https://channel9.msdn.com/Blogs/dotnet/Get-started-with-VS-Code-using-CSharp-and-NET-Core) - この [Channel9](https://channel9.msdn.com) ビデオでは、.NET Core で最初のコンソール アプリケーションを作成するために、Microsoft の簡易クロスプラットフォーム コード エディターである [Visual Studio Code](https://code.visualstudio.com/) をインストールして使用する方法を示します。 -* [Get Started with .NET Core and Visual Studio 2017](https://channel9.msdn.com/Blogs/dotnet/Get-Started-NET-Core-Visual-Studio-2017) (.NET Core および Visual Studio 2017 の概要) - この [Channel9](https://channel9.msdn.com) ビデオでは、.NET Core で最初のクロスプラットフォーム コンソール アプリケーションを作成するために、Microsoft のフル機能の IDE である [Visual Studio 2017](https://aka.ms/vsdownload?utm_source=mscom&utm_campaign=msdocs) をインストールして使用する方法を示します。 -* [コマンドラインを使用した .NET Core の概要](tutorials/using-with-xplat-cli.md) - [.NET Core クロスプラットフォーム コマンドライン インターフェイス (CLI)](tools/index.md) で任意のコード エディターを使用します。 +次に、**PowerShell**、**コマンド プロンプト**、**bash** などのターミナルを開きます。 次の `dotnet` コマンドを入力し、C# アプリケーションを作成して実行します。 -サポートされている Windows のバージョンの一覧については、[Windows 開発の前提条件](windows-prerequisites.md)に関するページをご覧ください。 +```console +dotnet new console --output sample1 +dotnet run --project sample1 +``` -## Linux +次の出力が表示されます。 -[Linux](https://www.microsoft.com/net/core#linuxredhat) に .NET Core をインストールします。 +```console +Hello World! +``` -次のステップ バイ ステップのチュートリアルに従って、.NET Core アプリの開発を開始できます。 +おめでとうございます! シンプルな .NET Core アプリケーションが作成されました。 [Visual Studio Code](tutorials/with-visual-studio-code.md)、[Visual Studio 2017](tutorials/with-visual-studio.md) (Windows のみ)、または [Visual Studio for Mac](tutorials/using-on-mac-vs.md) (macOS のみ) を使用して、.NET Core アプリケーションを作成することもできます。 -* [コマンドラインを使用した .NET Core の概要](tutorials/using-with-xplat-cli.md) - [.NET Core クロスプラットフォーム コマンドライン インターフェイス (CLI)](tools/index.md) で任意のコード エディターを使用します。 -* [Ubuntu で C# および .NET Core を使用した Visual Studio Code の概要](https://channel9.msdn.com/Blogs/dotnet/Get-started-with-VS-Code-Csharp-dotnet-Core-Ubuntu) - この [Channel9](https://channel9.msdn.com) ビデオでは、Ubuntu 14.04 上の .NET Core で最初のコンソール アプリケーションを作成するために、Microsoft の簡易クロスプラットフォーム コード エディターである [Visual Studio Code](https://code.visualstudio.com/) をインストールして使用する方法を示します。 +## チュートリアル + +次のステップ バイ ステップのチュートリアルに従って、.NET Core アプリケーションの開発を開始できます。 + +# [Windows](#tab/windows) + +* [Visual Studio 2017 での .NET Core を使用した C# Hello World アプリケーションの構築。](./tutorials/with-visual-studio.md) + +* [Visual Studio 2017 の C# および .NET Core を使用したクラス ライブラリの構築。](./tutorials/library-with-visual-studio.md) + +* [Visual Studio 2017 での .NET Core を使用した Visual Basic Hello World アプリケーションの構築。](./tutorials/vb-with-visual-studio.md) + +* [Visual Studio 2017 で Visual Basic と .NET Core を使用したクラス ライブラリの構築。](./tutorials/vb-library-with-visual-studio.md) + +* [Visual Studio Code と .NET Core をインストールして使用する方法](https://channel9.msdn.com/Blogs/dotnet/Get-started-with-VS-Code-using-CSharp-and-NET-Core/)に関するビデオを見る。 + +* [Visual Studio 2017 と .NET Core をインストールして使用する方法](https://channel9.msdn.com/Blogs/dotnet/Get-Started-NET-Core-Visual-Studio-2017/)に関するビデオを見る。 + +* [.NET Core でのコマンド ラインの使用に関する概要。](tutorials/using-with-xplat-cli.md) + +サポートされている Windows のバージョンの一覧については、[Windows 開発の前提条件](windows-prerequisites.md)に関する記事をご覧ください。 + +# [Linux](#tab/linux) + +次のステップ バイ ステップのチュートリアルに従って、.NET Core アプリケーションの開発を開始できます。 + +* [.NET Core でのコマンド ラインの使用に関する概要。](tutorials/using-with-xplat-cli.md) + +* [Ubuntu 上の Visual Studio Code での C# と .NET Core の使用に関する概要](https://channel9.msdn.com/Blogs/dotnet/Get-started-with-VS-Code-Csharp-dotnet-Core-Ubuntu)のビデオを見る。 サポートされている Linux ディストリビューションおよびバージョンの一覧については、[Linux 開発における前提条件](linux-prerequisites.md)に関する記事をご覧ください。 -## OS X / macOS +# [macOS](#tab/macos) + +次のステップ バイ ステップのチュートリアルに従って、.NET Core アプリケーションの開発を開始できます。 + +* [macOS 上の Visual Studio Code での C# と .NET Core の使用に関する概要](https://channel9.msdn.com/Blogs/dotnet/Get-started-VSCode-NET-Core-Mac)のビデオを見る。 + +* [macOS 上の .NET Core での Visual Studio Code の使用に関する概要。](tutorials/using-on-macos.md) + +* [.NET Core でのコマンド ラインの使用に関する概要。](tutorials/using-with-xplat-cli.md) -[macOS](https://www.microsoft.com/net/core#macos) に .NET Core をインストールします。 .NET Core は、OS X El Capitan (バージョン 10.11) および macOS Sierra (バージョン 10.12) でサポートされています。 +* [Visual Studio for Mac を使用した macOS での .NET Core の概要。](tutorials/using-on-mac-vs.md) -次のステップ バイ ステップのチュートリアルに従って、.NET Core アプリの開発を開始できます。 +* [Visual Studio for Mac を使用した macOS での完全な .NET Core ソリューションの構築。](tutorials/using-on-mac-vs-full-solution.md) -* [macOS で C# および .NET Core を使用した Visual Studio Code の概要](https://channel9.msdn.com/Blogs/dotnet/Get-started-VSCode-NET-Core-Mac) - この [Channel9](https://channel9.msdn.com) ビデオでは、.NET Core で最初のコンソール アプリケーションを作成するために、Microsoft の簡易クロスプラットフォーム コード エディターである [Visual Studio Code](https://code.visualstudio.com/) をインストールして使用する方法を示します。 -* [Visual Studio Code を使用した macOS での .NET Core の概要](tutorials/using-on-macos.md) - 単体テスト、サードパーティ製のライブラリ、デバッグ ツールの使用方法を含む、Visual Studio コードを使用した .NET Core ソリューションを作成するための手順やワークフローのツアーです。 -* [コマンドラインを使用した .NET Core の概要](tutorials/using-with-xplat-cli.md) - [.NET Core クロスプラットフォーム コマンドライン インターフェイス (CLI)](tools/index.md) で任意のコード エディターを使用します。 -* [Visual Studio for Mac を使用した macOS での .NET Core の概要](tutorials/using-on-mac-vs.md) - このチュートリアルでは、Visual Studio for Mac を使用して単純な .NET Core コンソール アプリケーションを構築する方法を示します。 -* [Visual Studio for Mac を使用した macOS での完全な .NET Core ソリューションの構築](tutorials/using-on-mac-vs-full-solution.md) - このチュートリアルでは、再利用可能なライブラリと単体テストを含む完全な .NET Core ソリューションを構築する方法を示します。 +サポートされている OS X または macOS のバージョンの一覧については、「[macOS における .NET Core の前提条件](macos-prerequisites.md)」の記事を参照してください。 -サポートされている OS X または macOS のバージョンの一覧については、「[Mac における .NET Core の前提条件](macos-prerequisites.md)」を参照してください。 +*** \ No newline at end of file diff --git a/docs/core/tools/dotnet-build-server.md b/docs/core/tools/dotnet-build-server.md index 13511d0ff1d..3003f9b2e15 100644 --- a/docs/core/tools/dotnet-build-server.md +++ b/docs/core/tools/dotnet-build-server.md @@ -1,17 +1,17 @@ --- -title: dotnet build-server コマンド - .NET Core CLI -description: dotnet build-server は、ビルドによって起動されたサーバーとやり取りします。 -author: mairaw -ms.author: mairaw -ms.date: 05/29/2018 -ms.openlocfilehash: 929b8d74aa5f3f0ad73b108be8a5bf22f86e30d6 -ms.sourcegitcommit: bbf70abe6b46073148f78cbf0619de6092b5800c -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/04/2018 -ms.locfileid: "34696255" +title: dotnet build-server コマンド - .NET Core CLI +description: dotnet build-server コマンドは、ビルドによって起動されたサーバーとやり取りします。 +author: mairaw +ms.author: mairaw +ms.date: 07/02/2018 +ms.openlocfilehash: 1c59c85f246b79c7e2552f704db5b4f076f9b502 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404334" --- -# dotnet-build +# dotnet build-server [!INCLUDE [topic-appliesto-net-core-21plus](../../../includes/topic-appliesto-net-core-21plus.md)] diff --git a/docs/core/versions/selection.md b/docs/core/versions/selection.md new file mode 100644 index 00000000000..d2cc09dd0ef --- /dev/null +++ b/docs/core/versions/selection.md @@ -0,0 +1,112 @@ +--- +title: .NET Core のバージョンの選択 +description: .NET Core がお使いのブログラムのランタイム バージョンを探し、選択するしくみについて説明します。 +author: billwagner +ms.author: wiwagn +ms.date: 06/27/2018 +ms.openlocfilehash: d1b885ebbade4736d5f592d1dc1d4ba25a321a16 +ms.sourcegitcommit: 59b51cd7c95c75be85bd6ef715e9ef8c85720bac +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/06/2018 +ms.locfileid: "37874471" +--- +# .NET Core のバージョンの選択 + +[!INCLUDE [topic-appliesto-net-core-2plus](../../../includes/topic-appliesto-net-core-2plus.md)] + +この記事では、.NET Core ツール、SDK、ランタイムによって使用されるバージョン選択ポリシーについて説明します。 これらのポリシーでは、指定バージョンを使用してアプリケーションを実行することと、開発者のコンピューターとエンド ユーザーのコンピューターの両方を簡単にアップグレードすることを両立させています。 これらのポリシーによって次が実行されます。 + +- セキュリティと信頼性の更新プログラムを含め、.NET Core を簡単かつ効率的に展開する。 +- ターゲット ランタイムとは関係なく、最新のツールとコマンドを使用する。 + +バージョンが次のように選択されます。 + +- SDK コマンドを実行すると、[SDK はインストールされている最新のバージョンを使用します](#the-sdk-uses-the-latest-installed-version)。 +- アセンブリをビルドすると、[ターゲット フレームワーク モニカーによってビルド時間 API が定義されます](#target-framework-monikers-define-build-time-apis)。 +- .NET Core アプリケーションを実行すると、[ターゲット フレームワークに依存するアプリがロールフォワードされます](#framework-dependent-apps-roll-forward)。 +- 自己完結型アプリケーションを公開するとき、[自己完結型の展開には選択されたランタイムが含まれます](#self-contained-deployments-include-the-selected-runtime)。 + +このドキュメントの残りの部分では、これら 4 つのシナリオについて説明します。 + +## SDK はインストールされている最新バージョンを使用する + +SDK コマンドには、`dotnet new`、`dotnet build`、`dotnet run` が含まれています。 `dotnet` CLI の場合、どのコマンドに対しても SDK バージョンを選択する必要があります。 .NET Core CLI では既定で、コンピューターにインストールされている最新の SDK が使用されます。 使用しているプロジェクトのターゲットが .NET Core Runtime 2.0 の場合でも、.NET Core SDK v2.1.301 がインストールされているとき、.NET Core SDK v2.1.301 が使用されます。 これはリリース バージョンと同様にプレビュー バージョンにも当てはまることにご注意ください。 以前のバージョンの .NET Core ランタイムをターゲットにしているとき、SDK の最新の機能と機能改善を活用できます。 すべてのプロジェクトに同じ SDK ツールを使用し、異なるプロジェクトで複数のランタイム バージョンの .NET Core をターゲットにできます。 + +まれに、以前のバージョンの SDK を使用する必要がある場合があります。 そのバージョンは [*global.json* ファイル](../tools/global-json.md)で指定します。 "最新版を使用する" というポリシーは、インストールされている最新版より以前のバージョンの .NET Core SDK を指定するには *global.json* を使用することを意味します。 + +*global.json* はファイル階層のどこにでも配置できます。 CLI はプロジェクト ディレクトリから上方を検索し、最初の *global.json* を見つけます。 ファイル システム内のその場所によって、特定の *global.json* が適用されるプロジェクトを制御します。 .NET CLI は、現在の作業ディレクトリからパスを上方に移動し、*global.json* ファイルを繰り返し検索します。 見つかった最初の *global.json* ファイルによって、使用されるバージョンが指定されます。 そのバージョンがインストールされている場合、そのバージョンが使用されます。 *global.json* に指定されている SDK が見つからない場合、.NET CLI はインストールされている最新の SDK にロールフォワードします。 *global.json* ファイルが見つからないとき、これは既定の動作と同じになります。 + +次の例は *global.json* 構文を示しています。 + +``` json +{ + "sdk": { + "version": "2.0.0" + } +} +``` + +SDK バージョンを選択するためのプロセス: + +1. `dotnet` は、現在の作業ディレクトリからパスを上方に逆移動し、*global.json* ファイルを繰り返し検索します。 +1. `dotnet` は見つかった最初の *global.json* に指定されている SDK を使用します。 +1. *global.json* が見つからない場合、`dotnet` はインストールされている最新の SDK を使用します。 + +SDK バージョンの選択に関する詳細は、*global.json* に関するトピックの「[matching rules](../tools/global-json.md)」(照合ルール) にあります。 + +## ターゲット フレームワーク モニカーによりビルド時間 API を定義する + +**ターゲット フレームワーク モニカー** (TFM) に定義されている API に対してプロジェクトをビルドします。 [ターゲット フレームワーク](../../standard/frameworks.md)はプロジェクト ファイルで指定します。 次の例のように、プロジェクト ファイルに `TargetFramework` 要素を設定します。 + +``` xml +netcoreapp2.0 +``` + +複数の TFM に対してプロジェクトをビルドできます。 複数のターゲット フレームワークを設定することはライブラリで一般的ですが、アプリケーションでも可能です。 `TargetFrameworks` プロパティ (`TargetFramework` の複数形) を指定します。 次の例のように、ターゲット フレームワークはセミコロンで区切られます。 + +``` xml +netcoreapp2.0;net47 +``` + +特定の SDK でサポートされる一連のフレームワークは決まっており、同梱のランタイムのターゲット フレームワークが上限となります。 たとえば、.NET Core 2.0 SDK には .NET Core 2.0 ランタイムが含まれますが、これは `netcoreapp2.0` ターゲット フレームワークの実装です。 .NET Core 2.0 SDK は `netcoreapp1.0`、`netcoreapp1.1`、`netcoreapp2.0` をサポートしますが、`netcoreapp2.1` (以降) はサポートされません。 `netcoreapp2.1` のビルドには、.NET Core 2.1 SDK をインストールします。 + +.NET Standard ターゲット フレームワークの上限も、SDK に付属するランタイムのターゲット フレームワークになります。 .NET Core 2.0 SDK の上限は `netstandard2.0` になります。 + +## フレームワーク依存のアプリをロールフォワードする + +[`dotnet run`](../tools/dotnet-run.md) を使用し、ソースからアプリケーションを実行します。 `dotnet run` はアプリケーションをビルドし、さらに実行します。 `dotnet` 実行可能ファイルは、開発環境においてアプリケーションの**ホスト**になります。 + +このホストがコンピューターにインストールされている最新版のパッチを選択します。 たとえば、プロジェクト ファイルに `netcoreapp2.0` を指定したとき、`2.0.4` がインストールされている最新の .NET ランタイムであれば、`2.0.4` ランタイムが使用されます。 + +許容される `2.0.*` バージョンが見つからない場合、新しい `2.*` バージョンが使用されます。 たとえば、`netcoreapp2.0` を指定したとき、`2.1.0` だけがインストールされている場合、アプリケーションは `2.1.0` ランタイムを利用して実行されます。 この動作は "マイナー バージョン ロールフォワード" と呼ばれます。 下位バージョンも考慮されません。 許容されるランタイムがインストールされていないとき、アプリケーションは実行されません。 + +以下にこの動作を示す使用例をいくつか示します。 + +- 2.0.4 が必須です。 インストールされているパッチ バージョンのうち、一番上が 2.0.5 です。 2.0.5 が使用されます。 +- 2.0.4 が必須です。 2.0.* バージョンはインストールされていません。 インストールされているランタイムのうち、一番上が 1.1.1 です。 エラー メッセージが表示されます。 +- 2.0.4 が必須です。 インストールされているバージョンのうち、一番上が 2.0.0 です。 エラー メッセージが表示されます。 +- 2.0.4 が必須です。 2.0.* バージョンはインストールされていません。 インストールされている 2.x ランタイム バージョンのうち、一番上が 2.2.2 です。 2.2.2 が使用されます。 +- 2.0.4 が必須です。 2.x バージョンはインストールされていません。 3.0.0 (現在のところ、利用できないバージョン) がインストールされています。 エラー メッセージが表示されます。 + +マイナー バージョン ロールフォワードには、エンド ユーザーに影響を与える可能性がある副作用が 1 つあります。 次のシナリオについて検討してください。 + +- 2.0.4 が必須です。 2.0.* バージョンはインストールされていません。 2.2.2 がインストールされています。 2.2.2 が使用されます。 +- 2.0.5 が後にインストールされます。 後にアプリケーションを起動したとき、2.2.2 ではなく、2.0.5 が使用されます。 必須のマイナー バージョンの最新のパッチが上位のマイナー バージョンより優先されます。 +- バイナリ データをシリアル化するなどのシナリオでは特に、2.0.5 と 2.2.2 の動作が異なることがあります。 + +## 自己完結型の展開に選択したランタイムが含まれる + +[**自己完結型ディストリビューション**](../deploying/index.md#self-contained-deployments-scd)としてアプリケーションを公開できます。 この手法では、.NET Core のランタイムとライブラリがアプリケーションと共にバンドルされます。 自己完結型の展開には、ランタイム環境に対する依存性がありません。 ランタイム バージョンは実行時ではなく、公開時に選択されます。 + +公開プロセスでは、特定のランタイム ファミリの最新版パッチが選択されます。 たとえば、`dotnet publish` では、.NET Core 2.0 ランタイム ファミリの最新版パッチが .NET Core 2.0.4 であればそれが選択されます。 ターゲット フレームワーク (インストールされているセキュリティ パッチを含む) がアプリケーションと共にパッケージ化されます。 + +アプリケーションに指定されている最小バージョンで十分ではない場合、エラーとなります。 `dotnet publish` は (特定の major.minor バージョン ファミリ内の) 最新ランタイム パッチ バージョンにバインドします。 `dotnet publish` は `dotnet run` のロールフォワード セマンティクスをサポートしません。 パッチや自己完結型の展開の詳細については、.NET Core アプリケーション展開の[ランタイム パッチ選択](../deploying/runtime-patch-selection.md)に関する記事を参照してください。 + +自己完結型の展開では、特定のパッチ バージョンが必要になることがあります。 次の例のように、プロジェクト ファイルで最小ランタイム パッチ バージョンを (上位または下位のバージョンに) オーバーライドできます。 + +``` xml +2.0.4 +``` + +`RuntimeFrameworkVersion` 要素は既定のバージョン ポリシーをオーバーライドします。 自己完結型の展開の場合、`RuntimeFrameworkVersion` によって*厳密な*ランタイム フレームワーク バージョンが指定されます。 フレームワーク依存アプリケーションの場合、`RuntimeFrameworkVersion` によって*最小限*必要なランタイム フレームワーク バージョンが指定されます。 diff --git a/docs/csharp/language-reference/keywords/global.md b/docs/csharp/language-reference/keywords/global.md index 07704b72a02..4b3f83d3d3d 100644 --- a/docs/csharp/language-reference/keywords/global.md +++ b/docs/csharp/language-reference/keywords/global.md @@ -1,26 +1,29 @@ --- -title: global (C# リファレンス) -ms.date: 07/20/2015 -f1_keywords: -- global -- global_CSharpKeyword -helpviewer_keywords: -- global keyword [C#] -ms.assetid: 8932c16a-6959-42c2-86e7-2c4221ab788b -ms.openlocfilehash: d6323f3b429b74c9b1f6e5d05c213d2e8f5a96c5 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33216040" +title: global コンテキスト キーワード (C# リファレンス) +ms.date: 07/20/2015 +f1_keywords: +- global +- global_CSharpKeyword +helpviewer_keywords: +- global keyword [C#] +ms.assetid: 8932c16a-6959-42c2-86e7-2c4221ab788b +ms.openlocfilehash: 79e0184f58ffc6232038abdd3d9f852147d5732c +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404289" --- # global (C# リファレンス) -[:: 演算子](../../../csharp/language-reference/operators/namespace-alias-qualifer.md)の前に来るとき、`global` コンテキスト キーワードは、C# プログラムの既定の名前空間であるグローバル名前空間を参照し、そうでない場合は名前のないグローバル名前空間を参照します。 詳細については、「[方法: グローバル名前空間エイリアスを使用する](../../../csharp/programming-guide/namespaces/how-to-use-the-global-namespace-alias.md)」を参照してください。 - -## 例 - 次の例では、コンテキスト キーワード `global` を利用し、グローバル名前空間でクラス `TestApp` が定義されることを指定しています。 - - [!code-csharp[csrefKeywordsContextual#13](../../../csharp/language-reference/keywords/codesnippet/CSharp/global_1.cs)] - -## 参照 - [名前空間](../../../csharp/programming-guide/namespaces/index.md) + +[:: 演算子](../operators/namespace-alias-qualifer.md)の前に来るとき、`global` コンテキスト キーワードは、C# プログラムの既定の名前空間であるグローバル名前空間を参照し、そうでない場合は名前のないグローバル名前空間を参照します。 詳細については、「[方法: グローバル名前空間エイリアスを使用する](../../programming-guide/namespaces/how-to-use-the-global-namespace-alias.md)」を参照してください。 + +## 例 + +次の例では、コンテキスト キーワード `global` を利用し、グローバル名前空間でクラス `TestApp` が定義されることを指定しています。 + +[!code-csharp[csrefKeywordsContextual#13](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsContextual/CS/csrefKeywordsContextual.cs#13)] + +## 関連項目 + +[名前空間](../../programming-guide/namespaces/index.md) \ No newline at end of file diff --git a/docs/csharp/language-reference/keywords/group-clause.md b/docs/csharp/language-reference/keywords/group-clause.md index 01c773aef25..355f712f0f2 100644 --- a/docs/csharp/language-reference/keywords/group-clause.md +++ b/docs/csharp/language-reference/keywords/group-clause.md @@ -1,87 +1,98 @@ --- -title: group 句 (C# リファレンス) -ms.date: 07/20/2015 -f1_keywords: -- group -- group_CSharpKeyword -helpviewer_keywords: -- group keyword [C#] -- group clause [C#] -ms.assetid: c817242e-b12c-4baa-a57e-73ee138f34d1 -ms.openlocfilehash: 2674986013afccf0a61267e49ca186d2ccb380e5 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33217485" +title: group 句 (C# リファレンス) +ms.date: 07/20/2015 +f1_keywords: +- group +- group_CSharpKeyword +helpviewer_keywords: +- group keyword [C#] +- group clause [C#] +ms.assetid: c817242e-b12c-4baa-a57e-73ee138f34d1 +ms.openlocfilehash: 8e3ddea3ba733cb9ba32e510b050a58407a7a477 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404516" --- # group 句 (C# リファレンス) -`group` 句は、グループのキー値に一致する 0 個以上の項目を含む オブジェクトのシーケンスを返します。 たとえば、各文字列の最初の文字に基づいて文字列のシーケンスをグループ化することができます。 この場合、最初の文字がキーで、型は [char](../../../csharp/language-reference/keywords/char.md) であり、各 オブジェクトの `Key` プロパティに格納されています。 コンパイラは、キーの型を推論します。 - - 次の例で示すように、クエリ式は `group` 句で終了できます。 - - [!code-csharp[cscsrefQueryKeywords#10](../../../csharp/language-reference/keywords/codesnippet/CSharp/group-clause_1.cs)] - - 各グループで追加のクエリ操作を実行する場合、[into](../../../csharp/language-reference/keywords/into.md) コンテキスト キーワードを使用して一時的な識別子を指定できます。 `into` を使用する場合、次の抜粋に示すように、クエリを続行し、最終的には `select` ステートメントまたは別の `group` 句でそれを終了する必要があります。 - - [!code-csharp[cscsrefQueryKeywords#11](../../../csharp/language-reference/keywords/codesnippet/CSharp/group-clause_2.cs)] - - このトピックの「例」のセクションでは、`into` を含む場合と含まない場合の `group` の使用方法の完全な例があります。 - -## グループ クエリの結果を列挙する - `group` クエリによって生成される オブジェクトは基本的には、リストのリストであるため、各グループのアイテムにアクセスするには、入れ子になった [foreach](../../../csharp/language-reference/keywords/foreach-in.md) ループを使用する必要があります。 外側のループがグループ キーを反復処理し、内側のループがグループ自体の各項目を反復処理します。 グループには、キーがある場合はありますが、要素はありません。 次に、前のコード例でクエリを実行する `foreach` ループを示します。 - - [!code-csharp[cscsrefQueryKeywords#12](../../../csharp/language-reference/keywords/codesnippet/CSharp/group-clause_3.cs)] - -## キーの種類 - グループ キーは、文字列、組み込みの数値型、またはユーザー定義の名前付きの型または匿名型など、任意の型にすることができます。 - -### 文字列でグループ化する - 前のコード例では、`char` を使用していました。 姓を完全に指定するなど、簡単に代わりに文字列のキーを指定できます。 - - [!code-csharp[cscsrefQueryKeywords#13](../../../csharp/language-reference/keywords/codesnippet/CSharp/group-clause_4.cs)] - -### ブールでグループ化する - 次の例では、結果を 2 つのグループに分割するためのキー用のブール値の用途を示します。 値は `group` 句のサブ式で生成されることに注意してください。 - - [!code-csharp[cscsrefQueryKeywords#14](../../../csharp/language-reference/keywords/codesnippet/CSharp/group-clause_5.cs)] - -### 数値の範囲でグループ化する - 次の例では、パーセンタイルの範囲を示す数値のグループ キーを作成する式を使用しています。 `group` 句でメソッドを 2 度呼び出さなくて済むように、メソッド呼び出しの結果を格納する便利な場所として [let](../../../csharp/language-reference/keywords/let-clause.md) を使用できます。 また、0 除算の例外を避けるために、受講者の平均が 0 でないことがコードの `group` 句で確認されています。 クエリ式でメソッドを安全に使用する方法の詳細については、「[方法: クエリ式の例外を処理する](../../../csharp/programming-guide/linq-query-expressions/how-to-handle-exceptions-in-query-expressions.md)」を参照してください。 - - [!code-csharp[cscsrefQueryKeywords#15](../../../csharp/language-reference/keywords/codesnippet/CSharp/group-clause_6.cs)] - -### 複合キーでグループ化する - 1 つ以上のキーを使用して要素をグループ化するには、複合キーを使用します。 複合キーは、キー要素を保持する、匿名型または名前付きの型を使用して作成できます。 次の例では、クラス `Person` が、`surname` と `city` という名前のメンバーで宣言されていると想定しています。 `group` 句により、同じ名前と同じ市の人物のセットごとに、別のグループが作成されます。 - -```csharp -group person by new {name = person.surname, city = person.city}; -``` - - クエリ変数を別のメソッドに渡す場合には、名前付きの型を使用します。 キーの自動実装プロパティを使用して特殊クラスを作成し、 メソッドと メソッドをオーバーライドします。 これらのメソッドを厳密にオーバーライドする必要がない構造体を使用することも可能です。 詳細については、「[方法 : 自動実装するプロパティを使用して簡易クラスを実装する](../../../csharp/programming-guide/classes-and-structs/how-to-implement-a-lightweight-class-with-auto-implemented-properties.md)」と「[Query for Duplicate Files in a Directory Tree](../../programming-guide/concepts/linq/how-to-query-for-duplicate-files-in-a-directory-tree-linq.md)」 (方法: ディレクトリ ツリーで重複するファイルを問い合わせる) を参照してください。 後述のトピックには、名前付きの型を複合キーで使用する方法のコード例があります。 - -## 例 - 次の例では、グループにその他のクエリ ロジックが適用されていない場合、ソース データをグループに並べる標準的なパターンを示します。 これは連結なしのグループ化と呼ばれます。 文字列の配列の要素は、最初の文字でグループ化されます。 クエリの結果は、型 `char` のパブリック `Key` プロパティを含む 型とグループに各項目を含む コレクションです。 - - `group` 句の結果は、シーケンスのシーケンスです。 そのため、返される各グループ内の各要素にアクセスするには、次の例のように、グループ キーを反復処理するループ内で入れ子になった `foreach` ループを使用します。 - - [!code-csharp[cscsrefQueryKeywords#16](../../../csharp/language-reference/keywords/codesnippet/CSharp/group-clause_7.cs)] - -## 例 - この例では、作成後に、`into` と共に *continuation* を使用し、グループに追加のロジックを実行する方法を示します。 詳しくは、「[into](../../../csharp/language-reference/keywords/into.md)」をご覧ください。 次の例では、キー値が母音であるものだけを選択するために各グループに問い合せを行います。 - - [!code-csharp[cscsrefQueryKeywords#17](../../../csharp/language-reference/keywords/codesnippet/CSharp/group-clause_8.cs)] - -## コメント - コンパイル時に `group` 句が メソッドの呼び出しに変換されます。 - -## 参照 - - - - - [クエリ キーワード (LINQ)](../../../csharp/language-reference/keywords/query-keywords.md) - [LINQ クエリ式](../../../csharp/programming-guide/linq-query-expressions/index.md) - [方法: 入れ子になったグループを作成する](../../../csharp/programming-guide/linq-query-expressions/how-to-create-a-nested-group.md) - [方法: クエリ結果をグループ化する](../../../csharp/programming-guide/linq-query-expressions/how-to-group-query-results.md) - [方法: グループ化操作でサブクエリを実行する](../../../csharp/programming-guide/linq-query-expressions/how-to-perform-a-subquery-on-a-grouping-operation.md) + +`group` 句は、グループのキー値に一致する 0 個以上の項目を含む オブジェクトのシーケンスを返します。 たとえば、各文字列の最初の文字に基づいて文字列のシーケンスをグループ化することができます。 この場合、最初の文字がキーで、型は [char](char.md) であり、各 オブジェクトの `Key` プロパティに格納されています。 コンパイラは、キーの型を推論します。 + +次の例で示すように、クエリ式は `group` 句で終了できます。 + +[!code-csharp[cscsrefQueryKeywords#10](~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsCsrefQueryKeywords/CS/Group.cs#10)] + +各グループで追加のクエリ操作を実行する場合、[into](into.md) コンテキスト キーワードを使用して一時的な識別子を指定できます。 `into` を使用する場合、次の抜粋に示すように、クエリを続行し、最終的には `select` ステートメントまたは別の `group` 句でそれを終了する必要があります。 + +[!code-csharp[cscsrefQueryKeywords#11](~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsCsrefQueryKeywords/CS/Group.cs#11)] + +この記事の「例」のセクションでは、`into` を含む場合と含まない場合の `group` の使用方法の完全な例があります。 + +## グループ クエリの結果を列挙する + +`group` クエリによって生成される オブジェクトは基本的には、リストのリストであるため、各グループのアイテムにアクセスするには、入れ子になった [foreach](foreach-in.md) ループを使用する必要があります。 外側のループがグループ キーを反復処理し、内側のループがグループ自体の各項目を反復処理します。 グループには、キーがある場合はありますが、要素はありません。 次に、前のコード例でクエリを実行する `foreach` ループを示します。 + +[!code-csharp[cscsrefQueryKeywords#12](~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsCsrefQueryKeywords/CS/Group.cs#12)] + +## キーの種類 + +グループ キーは、文字列、組み込みの数値型、またはユーザー定義の名前付きの型または匿名型など、任意の型にすることができます。 + +### 文字列でグループ化する + +前のコード例では、`char` を使用していました。 姓を完全に指定するなど、簡単に代わりに文字列のキーを指定できます。 + +[!code-csharp[cscsrefQueryKeywords#13](~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsCsrefQueryKeywords/CS/Group.cs#13)] + +### ブールでグループ化する + +次の例では、結果を 2 つのグループに分割するためのキー用のブール値の用途を示します。 値は `group` 句のサブ式で生成されることに注意してください。 + +[!code-csharp[cscsrefQueryKeywords#14](~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsCsrefQueryKeywords/CS/Group.cs#14)] + +### 数値の範囲でグループ化する + +次の例では、パーセンタイルの範囲を示す数値のグループ キーを作成する式を使用しています。 `group` 句でメソッドを 2 度呼び出さなくて済むように、メソッド呼び出しの結果を格納する便利な場所として [let](let-clause.md) を使用できます。 また、"0 除算" の例外を避けるために、受講者の平均が 0 でないことがコードの `group` 句で確認されています。 クエリ式でメソッドを安全に使用する方法の詳細については、「[方法: クエリ式の例外を処理する](../../programming-guide/linq-query-expressions/how-to-handle-exceptions-in-query-expressions.md)」を参照してください。 + +[!code-csharp[cscsrefQueryKeywords#15](~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsCsrefQueryKeywords/CS/Group.cs#15)] + +### 複合キーでグループ化する + +1 つ以上のキーを使用して要素をグループ化するには、複合キーを使用します。 複合キーは、キー要素を保持する、匿名型または名前付きの型を使用して作成できます。 次の例では、クラス `Person` が、`surname` と `city` という名前のメンバーで宣言されていると想定しています。 `group` 句により、同じ名前と同じ市の人物のセットごとに、別のグループが作成されます。 + +```csharp +group person by new {name = person.surname, city = person.city}; +``` + +クエリ変数を別のメソッドに渡す場合には、名前付きの型を使用します。 キーの自動実装プロパティを使用して特殊クラスを作成し、 メソッドと メソッドをオーバーライドします。 これらのメソッドを厳密にオーバーライドする必要がない構造体を使用することも可能です。 詳細については、「[方法 : 自動実装するプロパティを使用して簡易クラスを実装する](../../programming-guide/classes-and-structs/how-to-implement-a-lightweight-class-with-auto-implemented-properties.md)」と「[Query for Duplicate Files in a Directory Tree](../../programming-guide/concepts/linq/how-to-query-for-duplicate-files-in-a-directory-tree-linq.md)」 (方法: ディレクトリ ツリーで重複するファイルを問い合わせる) を参照してください。 後述の記事には、名前付きの型を複合キーで使用する方法のコード例があります。 + +## 例 + +次の例では、グループにその他のクエリ ロジックが適用されていない場合、ソース データをグループに並べる標準的なパターンを示します。 これは連結なしのグループ化と呼ばれます。 文字列の配列の要素は、最初の文字でグループ化されます。 クエリの結果は、型 `char` のパブリック `Key` プロパティを含む 型とグループに各項目を含む コレクションです。 + +`group` 句の結果は、シーケンスのシーケンスです。 そのため、返される各グループ内の各要素にアクセスするには、次の例のように、グループ キーを反復処理するループ内で入れ子になった `foreach` ループを使用します。 + +[!code-csharp[cscsrefQueryKeywords#16](~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsCsrefQueryKeywords/CS/Group.cs#16)] + +## 例 + +この例では、作成後に、`into` と共に *continuation* を使用し、グループに追加のロジックを実行する方法を示します。 詳しくは、「[into](into.md)」をご覧ください。 次の例では、キー値が母音であるものだけを選択するために各グループに問い合せを行います。 + +[!code-csharp[cscsrefQueryKeywords#17](~/samples/snippets/csharp/VS_Snippets_VBCSharp/CsCsrefQueryKeywords/CS/Group.cs#17)] + +## コメント + +コンパイル時に `group` 句が メソッドの呼び出しに変換されます。 + +## 関連項目 + + + + + +[クエリ キーワード](query-keywords.md) +[統合言語クエリ (LINQ)](../../linq/index.md) +[入れ子になったグループの作成](../../linq/create-a-nested-group.md) +[クエリ結果のグループ化](../../linq/group-query-results.md) +[グループ化操作でのサブクエリの実行](../../linq/perform-a-subquery-on-a-grouping-operation.md) \ No newline at end of file diff --git a/docs/csharp/language-reference/keywords/readonly.md b/docs/csharp/language-reference/keywords/readonly.md index 4cf07c0ed9f..3a91a6ab7a6 100644 --- a/docs/csharp/language-reference/keywords/readonly.md +++ b/docs/csharp/language-reference/keywords/readonly.md @@ -1,64 +1,103 @@ --- -title: readonly (C# リファレンス) -ms.date: 07/20/2015 -f1_keywords: -- readonly_CSharpKeyword -- readonly -helpviewer_keywords: -- readonly keyword [C#] -ms.assetid: 2f8081f6-0de2-4903-898d-99696c48d2f4 -ms.openlocfilehash: d2f8a2f192dc319ad806aeef4bfbaeecc44b07a3 -ms.sourcegitcommit: 89c93d05c2281b4c834f48f6c8df1047e1410980 -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/15/2018 -ms.locfileid: "34172634" +title: readonly キーワード (C# リファレンス) +ms.date: 06/21/2018 +f1_keywords: +- readonly_CSharpKeyword +- readonly +helpviewer_keywords: +- readonly keyword [C#] +ms.assetid: 2f8081f6-0de2-4903-898d-99696c48d2f4 +ms.openlocfilehash: 96607f1dd7f019169446e29a08496fb54e1ed493 +ms.sourcegitcommit: 60645077dc4b62178403145f8ef691b13ffec28e +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/10/2018 +ms.locfileid: "37961184" --- # readonly (C# リファレンス) -`readonly` キーワードは、フィールドで使用できる修飾子です。 フィールド宣言に `readonly` 修飾子が含まれていると、その宣言によって導入されるフィールドへの割り当ては、宣言の一部分として、または同じクラスのコンストラクター内でのみ実行できます。 - + +`readonly` キーワードは、3 つのコンテキストで使用できる修飾子です。 + +- [フィールドの宣言](#readonly-field-example)では、`readonly` は、フィールドへの割り当てが、宣言の一部として、または同じクラスのコンストラクター内でのみ可能であることを示します。 +- [`readonly struct` の定義](#readonly-struct-example)では、`readonly` は `struct` が変更不可であることを示します。 +- [`ref readonly` メソッドの戻り値](#ref-readonly-return-example)では、`readonly` 修飾子は、メソッドが参照を返し、その参照への書き込みが許可されないことを示します。 + +最後の 2 つのコンテキストは、C# 7.2 で追加されました。 + ## 読み取り専用フィールドの例 - この例では、`year` フィールドの値は、クラス コンストラクターで値が割り当てられていても `ChangeYear` メソッドでは変更できません。 - - [!code-csharp[csrefKeywordsModifiers#14](../../../csharp/language-reference/keywords/codesnippet/CSharp/readonly_1.cs)] - - `readonly` のフィールドに値を割り当てることができるのは、次のコンテキスト内に限られます。 + +この例では、`year` フィールドの値は、クラス コンストラクターで値が割り当てられていても `ChangeYear` メソッドでは変更できません。 -- 値が宣言で初期化される場合。次に例を示します。 +[!code-csharp[Readonly Field example](~/samples/snippets/csharp/keywords/ReadonlyKeywordExamples.cs#ReadonlyField)] - ```csharp - public readonly int y = 5; - ``` +`readonly` のフィールドに値を割り当てることができるのは、次のコンテキスト内に限られます。 -- インスタンス フィールドの場合は、フィールド宣言が含まれるクラスのインスタンス コンストラクター内。静的フィールドの場合は、フィールド宣言が含まれるクラスの静的コンストラクター内。 また、こうしたコンテキスト内でのみ、`readonly` フィールドを [out](../../../csharp/language-reference/keywords/out-parameter-modifier.md) パラメーターまたは [ref](../../../csharp/language-reference/keywords/ref.md) パラメーターとして渡すことができます。 +- 値が宣言で初期化される場合。次に例を示します。 + +```csharp +public readonly int y = 5; +``` + +- インスタンス フィールド宣言を含むクラスのインスタンス コンストラクター内。 +- 静的フィールド宣言を含むクラスの静的コンストラクター内。 + +また、これらのコンストラクター コンテキスト内でのみ、`readonly` フィールドを [out](out-parameter-modifier.md) パラメーターまたは [ref](ref.md) パラメーターとして渡すことができます。 > [!NOTE] -> `readonly` キーワードは [const](../../../csharp/language-reference/keywords/const.md) キーワードとは異なります。 `const` フィールドは、フィールドの宣言でしか初期化できません。 `readonly` フィールドは、宣言またはコンストラクターのどちらかで初期化できます。 このため、`readonly` フィールドは、使用するコンストラクターに応じて異なる値を持つことができます。 また、次の例のように、`const` フィールドがコンパイル時定数であるのに対し、`readonly` フィールドは実行時定数として使用できます。 - -```csharp +> `readonly` キーワードは [const](const.md) キーワードとは異なります。 `const` フィールドは、フィールドの宣言でしか初期化できません。 `readonly` フィールドは、宣言またはコンストラクターのどちらかで初期化できます。 このため、`readonly` フィールドは、使用するコンストラクターに応じて異なる値を持つことができます。 また、次の例のように、`const` フィールドがコンパイル時定数であるのに対し、`readonly` フィールドは実行時定数として使用できます。 + +```csharp public static readonly uint timeStamp = (uint)DateTime.Now.Ticks; -``` - -## 読み取り専用と読み取り専用以外のインスタンス フィールドの比較 - [!code-csharp[csrefKeywordsModifiers#15](../../../csharp/language-reference/keywords/codesnippet/CSharp/readonly_2.cs)] - - 上の例で、次のようにステートメントを使用するとします。 - - `p2.y = 66; // Error` - - この場合、次のコンパイル エラー メッセージが表示されます。 - - `The left-hand side of an assignment must be an l-value` - - これは、定数に値を割り当てようとしたときのエラーと同じです。 - +``` + +[!code-csharp[Initialize readonly Field example](~/samples/snippets/csharp/keywords/ReadonlyKeywordExamples.cs#InitReadonlyField)] + +上の例で、次の例のようなステートメントを使うものとします。 + +`p2.y = 66; // Error` + +この場合、次のコンパイル エラー メッセージが表示されます。 + +`The left-hand side of an assignment must be an l-value` + +これは、定数に値を割り当てようとしたときのエラーと同じです。 + +## 読み取り専用の構造体の例 + +`struct` 定義での `readonly` 修飾子は、構造体が**変更不可**であることを宣言します。 次の例のように、`struct` のすべてのインスタンス フィールドを `readonly` とマークする必要があります。 + +[!code-csharp[readonly struct example](~/samples/snippets/csharp/keywords/ReadonlyKeywordExamples.cs#ReadonlyStruct)] + +前の例では、[読み取り専用の自動プロパティ](../../properties.md#read-only)を使ってその記憶域を宣言しています。 これは、これらのプロパティに対して `readonly` バッキング フィールドを作成するようコンパイラに指示します。 `readonly` フィールドを直接宣言することもできます。 + +```csharp +public readonly struct Point +{ + public readonly double X; + public readonly double Y; + + public Point(double x, double y) => (X, Y) = (x, y); + + public override string ToString() => $"({X}, {Y})"; +} +``` + +`readonly` に指定されていないフィールドを追加すると、コンパイラ エラー `CS8340`: "読み取り専用の構造体のインスタンス フィールドは、読み取り専用である必要があります" が生成されます。 + +## ref readonly の戻り値の例 + +`ref return` での `readonly` 修飾子は、返される参照を変更できないことを示します。 次の例は、origin に参照を返します。 `readonly` 修飾子を使用して、呼び出し元が origin を変更できないことを示しています。 + +[!code-csharp[readonly struct example](~/samples/snippets/csharp/keywords/ReadonlyKeywordExamples.cs#ReadonlyReturn)] +返される型を `readonly struct` にする必要はありません。 `ref` で返すことができる任意の型を、`ref readonly` で返すことができます。 + ## C# 言語仕様 - [!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)] +[!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)] ## 参照 - [C# リファレンス](../../../csharp/language-reference/index.md) - [C# プログラミング ガイド](../../../csharp/programming-guide/index.md) - [C# のキーワード](../../../csharp/language-reference/keywords/index.md) - [修飾子](../../../csharp/language-reference/keywords/modifiers.md) - [const](../../../csharp/language-reference/keywords/const.md) - [フィールド](../../../csharp/programming-guide/classes-and-structs/fields.md) +[C# リファレンス](../../../csharp/language-reference/index.md) +[C# プログラミング ガイド](../../../csharp/programming-guide/index.md) +[C# のキーワード](../../../csharp/language-reference/keywords/index.md) +[修飾子](../../../csharp/language-reference/keywords/modifiers.md) +[const](../../../csharp/language-reference/keywords/const.md) +[フィールド](../../../csharp/programming-guide/classes-and-structs/fields.md) diff --git a/docs/csharp/language-reference/keywords/ref.md b/docs/csharp/language-reference/keywords/ref.md index 0f9408799b6..bd8278759f3 100644 --- a/docs/csharp/language-reference/keywords/ref.md +++ b/docs/csharp/language-reference/keywords/ref.md @@ -1,35 +1,34 @@ --- -title: ref (C# リファレンス) -ms.date: 03/06/2018 -f1_keywords: -- ref_CSharpKeyword -- ref -helpviewer_keywords: -- parameters [C#], ref -- ref keyword [C#] -ms.openlocfilehash: a4d5719bccd240658880cc5c6e549e8c912ca1b9 -ms.sourcegitcommit: bbf70abe6b46073148f78cbf0619de6092b5800c -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/04/2018 -ms.locfileid: "34696395" +title: ref (C# リファレンス) +ms.date: 03/06/2018 +f1_keywords: +- ref_CSharpKeyword +- ref +helpviewer_keywords: +- parameters [C#], ref +- ref keyword [C#] +ms.openlocfilehash: a72624d5702ec12bfda98d49a16474cc84205ff0 +ms.sourcegitcommit: 70c76a12449439bac0f7a359866be5a0311ce960 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/25/2018 +ms.locfileid: "39245753" --- # ref (C# リファレンス) -`ref` キーワードは、参照渡しで渡される値を示します。 このキーワードは、3 つの異なるコンテキストで使用されます。 +`ref` キーワードは、参照渡しで渡される値を示します。 このキーワードは、4 つの異なるコンテキストで使用されます。 - メソッド シグネチャとメソッドの呼び出しで、参照によってメソッドに引数を渡します。 詳細については、「[参照渡しで引数を渡す](#passing-an-argument-by-reference)」を参照してください。 - - メソッド シグネチャで、参照渡しで呼び出し元に値を返します。 詳細については、「[参照戻り値](#reference-return-values)」を参照してください。 - - メンバーの本文で、参照戻り値が、呼び出し元によって変更される参照としてローカルに格納されること、または、通常はローカル変数が参照渡しによって別の値にアクセスすることを示します。 詳細については、「[ref ローカル変数](#ref-locals)」を参照してください。 +- `struct` の宣言で、`ref struct` または `ref readonly struct` を宣言します。 詳しくは、「[ref struct 宣言](#ref-struct-declarations)」をご覧ください。 ## 参照渡しで引数を渡す メソッドのパラメーター リストで使用した場合、`ref` キーワードは、引数を値ではなく、参照によって渡すことを示します。 参照渡しで渡すことにより、呼び出されたメソッドの引数に対する変更が、呼び出し元のメソッドに反映されます。 たとえば、呼び出し元がローカル変数の式、または配列要素のアクセス式を渡し、呼び出されたメソッドが ref パラメーターが参照するオブジェクトを置き換える場合、メソッドが戻ったときに呼び出し元のローカル変数または配列要素は新しいオブジェクトを参照します。 > [!NOTE] -> 参照渡しの概念と参照型の概念を混同しないでください。 2 つの概念は同じではありません。 メソッドのパラメーターは、値型か参照型かどうかに関係なく、`ref` によって変更できます。 参照渡しで渡される場合、値型はボックス化されません。 +> 参照渡しの概念と参照型の概念を混同しないでください。 2 つの概念は同じではありません。 メソッドのパラメーターは、値型か参照型かどうかに関係なく、`ref` によって変更できます。 参照渡しで渡される場合、値型はボックス化されません。 `ref` パラメーターを使用するには、メソッド定義と呼び出し元のメソッドの両方が、次の例に示すように `ref` キーワードを明示的に使用する必要があります。 @@ -48,6 +47,7 @@ class CS0663_Example public void SampleMethod(ref int i) { } } ``` + ただし、次の例に示すように、1 つのメソッドに `ref`、`in` または `out` パラメーターがあり、もう 1 つのメソッドに値パラメーターがある場合、メソッドをオーバーロードすることができます。 [!code-csharp[csrefKeywordsMethodParams#6](../../../../samples/snippets/csharp/language-reference/keywords/in-ref-out-modifier/RefParameterModifier.cs#2)] @@ -65,7 +65,7 @@ class CS0663_Example ## 参照渡しで引数を渡す: 使用例 -前の例は、参照によって値型を渡す例でした。 `ref` キーワードを使用して、参照渡しで参照型を渡すこともできます。 参照型を参照渡しで渡すと、呼び出されたメソッドは、参照パラメーターが呼び出し元で参照するオブジェクトに置換できます。 オブジェクトの格納場所は、参照パラメーターの値としてメソッドに渡されます。 パラメーターの格納場所の値を変更する場合は (新しいオブジェクトをポイント)、呼び出し元が参照する格納場所を変更することもできます。 次の例では、参照型のインスタンスを `ref` パラメーターとして渡します。 +前の例は、参照によって値型を渡す例でした。 `ref` キーワードを使用して、参照渡しで参照型を渡すこともできます。 参照型を参照渡しで渡すと、呼び出されたメソッドは、参照パラメーターが呼び出し元で参照するオブジェクトに置換できます。 オブジェクトの格納場所は、参照パラメーターの値としてメソッドに渡されます。 パラメーターの格納場所の値を変更する場合は (新しいオブジェクトをポイント)、呼び出し元が参照する格納場所を変更することもできます。 次の例では、参照型のインスタンスを `ref` パラメーターとして渡します。 [!code-csharp[csrefKeywordsMethodParams#6](../../../../samples/snippets/csharp/language-reference/keywords/in-ref-out-modifier/RefParameterModifier.cs#3)] @@ -73,22 +73,23 @@ class CS0663_Example ## 参照戻り値 -参照戻り値 (または ref 戻り値) は、メソッドから呼び出し元に参照渡しで返される値です。 つまり、呼び出し元はメソッドによって返される値を変更することができ、メソッドを格納するオブジェクトの状態にその変更が反映されます。 +参照戻り値 (または ref 戻り値) は、メソッドから呼び出し元に参照渡しで返される値です。 つまり、呼び出し元はメソッドによって返される値を変更することができ、メソッドを格納するオブジェクトの状態にその変更が反映されます。 参照戻り値は `ref` キーワードを使用して以下に定義されます。 - メソッド シグネチャ。 たとえば、次のメソッド シグネチャは、`GetCurrentPrice` メソッドが参照渡しで 値を返すことを示しています。 - ```csharp - public ref decimal GetCurrentValue() - ``` +```csharp +public ref decimal GetCurrentValue() +``` + - メソッドの `return` ステートメントで返される変数と `return` トークンの間。 例: - - ```csharp - return ref DecimalArray[0]; - ``` -呼び出し元がオブジェクトの状態を変更するには、[ref ローカル変数](#ref-locals)として明示的に定義した変数に参照戻り値を格納する必要があります。 +```csharp +return ref DecimalArray[0]; +``` + +呼び出し元がオブジェクトの状態を変更するには、[ref ローカル変数](#ref-locals)として明示的に定義した変数に参照戻り値を格納する必要があります。 例については、「[ref 戻り値と ref ローカル変数](#a-ref-returns-and-ref-locals-example)」を参照してください。 @@ -96,7 +97,7 @@ class CS0663_Example ref ローカル変数は、`return ref` を使用して返された値を参照するために使用します。 ref ローカル変数は、初期化して ref 戻り値に割り当てる必要があります。 ref ローカル変数の値に変更を加えると、参照渡しの値を返すメソッドのオブジェクトの状態に反映されます。 -ref ローカル変数を定義するには、変数宣言の前と、参照渡しで値を返すメソッドの呼び出しの直前に、`ref` キーワードを使用します。 +ref ローカル変数を定義するには、変数宣言の前と、参照渡しで値を返すメソッドの呼び出しの直前に、`ref` キーワードを使用します。 たとえば、次のステートメントは、`GetEstimatedValue` という名前のメソッドによって返される ref ローカル変数を定義しています。 @@ -110,8 +111,8 @@ ref decimal estValue = ref Building.GetEstimatedValue(); ref VeryLargeStruct reflocal = ref veryLargeStruct; ``` -どちらの例も、`ref` キーワードは両方の位置で使用する必要があります。そうしないと、コンパイラ エラー CS8172 "値を使用して参照渡し変数を初期化することはできません" が生成されます。 - +どちらの例も、`ref` キーワードは両方の位置で使用する必要があります。そうしないと、コンパイラ エラー CS8172 "値を使用して参照渡し変数を初期化することはできません" が生成されます。 + ## ref 戻り値と ref ローカル変数の使用例 次の例は、`Title` と `Author` という 2 つの フィールドを持つ `Book` クラスを定義しています。 また、`Book` オブジェクトのプライベート配列を含む `BookCollection` クラスも定義しています。 個々のブック オブジェクトは、`GetBookByTitle` メソッドを呼び出すことによって参照渡しで返されます。 @@ -122,10 +123,14 @@ ref VeryLargeStruct reflocal = ref veryLargeStruct; [!code-csharp[csrefKeywordsMethodParams#6](../../../../samples/snippets/csharp/language-reference/keywords/in-ref-out-modifier/RefParameterModifier.cs#5)] -## C# 言語仕様 - [!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)] +## ref struct 宣言 + +## C# 言語仕様 + +[!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)] -## 関連項目 +## 関連項目 + [値の型による参照セマンティクス](../../reference-semantics-with-value-types.md) [パラメーターの引き渡し](../../programming-guide/classes-and-structs/passing-parameters.md) [メソッド パラメーター](method-parameters.md) diff --git a/docs/csharp/language-reference/keywords/volatile.md b/docs/csharp/language-reference/keywords/volatile.md index 91c07b7e86d..fec6a09c252 100644 --- a/docs/csharp/language-reference/keywords/volatile.md +++ b/docs/csharp/language-reference/keywords/volatile.md @@ -1,21 +1,21 @@ --- -title: volatile (C# リファレンス) -ms.date: 07/20/2015 -f1_keywords: -- volatile_CSharpKeyword -- volatile -helpviewer_keywords: -- volatile keyword [C#] -ms.assetid: 78089bc7-7b38-4cfd-9e49-87ac036af009 -ms.openlocfilehash: 7f3aafc1255667f2a3917c6e171ce4ddf0343b41 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33272585" +title: volatile (C# リファレンス) +ms.date: 07/20/2015 +f1_keywords: +- volatile_CSharpKeyword +- volatile +helpviewer_keywords: +- volatile keyword [C#] +ms.assetid: 78089bc7-7b38-4cfd-9e49-87ac036af009 +ms.openlocfilehash: 64bd5ce7d7dfe3265c3c645467493ab7d8792172 +ms.sourcegitcommit: 60645077dc4b62178403145f8ef691b13ffec28e +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/10/2018 +ms.locfileid: "37936879" --- # volatile (C# リファレンス) -`volatile` キーワードは、同時に実行されている複数のスレッドによって、フィールドが変更される可能性があることを示します。 `volatile` と宣言されているフィールドは、シングル スレッドによるアクセスを前提とする、コンパイラの最適化の対象にはなりません。 このため、フィールドには常に最新の値が含まれます。 +`volatile` キーワードは、同時に実行されている複数のスレッドによって、フィールドが変更される可能性があることを示します。 `volatile` と宣言されているフィールドは、シングル スレッドによるアクセスを前提とする、コンパイラの最適化の対象にはなりません。 これらの制限により、すべてのスレッドが、他のスレッドによって実行された volatile の書き込みを、実行された順序で観察することが保証されます。 volatile 書き込みの単一の全体的順序がすべての実行スレッドから認識される保証はありません。 `volatile` 修飾子は、通常、アクセスをシリアル化する [lock](../../../csharp/language-reference/keywords/lock-statement.md) ステートメントが使用されない場合に、複数のスレッドからアクセスされるフィールドに対して使用します。 @@ -41,7 +41,7 @@ ms.locfileid: "33272585" [!code-csharp[csrefKeywordsModifiers#24](../../../csharp/language-reference/keywords/codesnippet/CSharp/volatile_1.cs)] ## 例 - 次の例は、補助スレッドつまりワーカー スレッドを作成および使用して、プライマリ スレッドとの並行処理を実行する方法を示しています。 マルチスレッドの背景情報については、[スレッド化 (C#)](../../../standard/threading/index.md) と[マネージド スレッド処理](../../programming-guide/concepts/threading/index.md)に関するページを参照してください。 + 次の例は、補助スレッドつまりワーカー スレッドを作成および使用して、プライマリ スレッドとの並行処理を実行する方法を示しています。 マルチスレッドの背景情報については、「[マネージド スレッド処理](../../../standard/threading/index.md)」および「[スレッド処理 (C#)](../../programming-guide/concepts/threading/index.md)」をご覧ください。 [!code-csharp[csProgGuideThreading#1](../../../csharp/language-reference/keywords/codesnippet/CSharp/volatile_2.cs)] diff --git a/docs/csharp/language-reference/preprocessor-directives/preprocessor-define.md b/docs/csharp/language-reference/preprocessor-directives/preprocessor-define.md index 5718d381310..6dd878c8ab7 100644 --- a/docs/csharp/language-reference/preprocessor-directives/preprocessor-define.md +++ b/docs/csharp/language-reference/preprocessor-directives/preprocessor-define.md @@ -1,17 +1,17 @@ --- -title: '#define (C# リファレンス)' -ms.date: 07/20/2015 -f1_keywords: -- '#define' -helpviewer_keywords: -- '#define directive [C#]' -ms.assetid: 23638b8f-779c-450e-b600-d55682de7d01 -ms.openlocfilehash: 1903b96de5f9dfa4efc252897a4a4bd18ed64924 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33286735" +title: '#define (C# リファレンス)' +ms.date: 06/30/2018 +f1_keywords: +- '#define' +helpviewer_keywords: +- '#define directive [C#]' +ms.assetid: 23638b8f-779c-450e-b600-d55682de7d01 +ms.openlocfilehash: f40c32a89641256e4f8fe30cd24f523b898139d5 +ms.sourcegitcommit: dc02d7d95f1e3efcc7166eaf431b0ec0dc9d8dca +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/02/2018 +ms.locfileid: "37143480" --- # #define (C# リファレンス) `#define` は、シンボルを定義するために使用します。 次の例に示すように、定義したシンボルを式として [#if](../../../csharp/language-reference/preprocessor-directives/preprocessor-if.md) ディレクティブに渡すと、式は `true` と評価されます。 @@ -29,9 +29,9 @@ ms.locfileid: "33286735" シンボルを定義することはできますが、シンボルに値は代入できません。 `#define` ディレクティブは、ファイル内で、プリプロセッサ ディレクティブではない他の命令よりも前に記述する必要があります。 - また、シンボルは [/define](../../../csharp/language-reference/compiler-options/define-compiler-option.md) コンパイラ オプションでも定義できます。 [#undef](../../../csharp/language-reference/preprocessor-directives/preprocessor-undef.md) を使うと、シンボルを未定義状態にできます。 + シンボルは、[-define](../../../csharp/language-reference/compiler-options/define-compiler-option.md) コンパイラ オプションでも定義できます。 [#undef](../../../csharp/language-reference/preprocessor-directives/preprocessor-undef.md) を使うと、シンボルを未定義状態にできます。 - `/define` または `#define` で定義されたシンボルは、同じ名前の変数とは競合しません。 変数名をプリプロセッサ ディレクティブに渡すことはできません。シンボルはプリプロセッサ ディレクティブだけで評価されます。 + `-define` または `#define` で定義されたシンボルは、同じ名前の変数とは競合しません。 変数名をプリプロセッサ ディレクティブに渡すことはできません。シンボルはプリプロセッサ ディレクティブだけで評価されます。 `#define` で定義されたシンボルのスコープは、そのシンボルが定義されたファイル内だけです。 diff --git a/docs/csharp/language-reference/preprocessor-directives/preprocessor-undef.md b/docs/csharp/language-reference/preprocessor-directives/preprocessor-undef.md index 46c178c733b..26786718ea6 100644 --- a/docs/csharp/language-reference/preprocessor-directives/preprocessor-undef.md +++ b/docs/csharp/language-reference/preprocessor-directives/preprocessor-undef.md @@ -1,22 +1,22 @@ --- -title: '#undef (C# リファレンス)' -ms.date: 07/20/2015 -f1_keywords: -- '#undef' -helpviewer_keywords: -- '#undef directive [C#]' -ms.assetid: 686c92d2-7194-4be4-b2f4-80091712d513 -ms.openlocfilehash: 870b78580e5350f06fae33f2ac107dc3968b2c6e -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33273411" +title: '#undef (C# リファレンス)' +ms.date: 06/30/2018 +f1_keywords: +- '#undef' +helpviewer_keywords: +- '#undef directive [C#]' +ms.assetid: 686c92d2-7194-4be4-b2f4-80091712d513 +ms.openlocfilehash: 2877ab7cb1b124dd26a76766cdc9940caf454f4e +ms.sourcegitcommit: dc02d7d95f1e3efcc7166eaf431b0ec0dc9d8dca +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/02/2018 +ms.locfileid: "37143493" --- # #undef (C# リファレンス) `#undef` を使用すると、シンボルを未定義にすることができます。未定義のシンボルを [#if](../../../csharp/language-reference/preprocessor-directives/preprocessor-if.md) ディレクティブで式として使用すると、その式は `false` と評価されます。 - シンボルは、[#define](../../../csharp/language-reference/preprocessor-directives/preprocessor-define.md) ディレクティブまたは [/define](../../../csharp/language-reference/compiler-options/define-compiler-option.md) コンパイラ オプションで定義できます。 `#undef` ディレクティブは、ファイル内で、ディレクティブではない他のステートメントよりも前に記述する必要があります。 + シンボルは、[#define](../../../csharp/language-reference/preprocessor-directives/preprocessor-define.md) ディレクティブまたは [-define](../../../csharp/language-reference/compiler-options/define-compiler-option.md) コンパイラ オプションのいずれかで定義できます。 `#undef` ディレクティブは、ファイル内で、ディレクティブではない他のステートメントよりも前に記述する必要があります。 ## 例 diff --git a/docs/csharp/linq/create-a-nested-group.md b/docs/csharp/linq/create-a-nested-group.md index 731fcbcc56b..86906679eba 100644 --- a/docs/csharp/linq/create-a-nested-group.md +++ b/docs/csharp/linq/create-a-nested-group.md @@ -1,27 +1,28 @@ --- -title: 入れ子になったグループの作成 -description: 入れ子になったグループを作成する方法。 -ms.date: 12/1/2016 -ms.assetid: e9f00708-362e-4d13-98c5-d77549347ba0 -ms.openlocfilehash: dd1158bfa1456342fe8967aed5e02ecebae591c1 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33273144" +title: 入れ子になったグループの作成 (C# での LINQ) +description: C# で LINQ クエリ式に入れ子になったグループを作成する方法について説明します。 +ms.date: 12/1/2016 +ms.assetid: e9f00708-362e-4d13-98c5-d77549347ba0 +ms.openlocfilehash: c973048d0859f61596c62c294131b8c00d0039f8 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404750" --- # 入れ子になったグループの作成 -LINQ クエリ式で入れ子になったグループを作成する方法を次の例に示します。 学年レベルに基づいて作成した各グループを、さらに個人の名前に基づくグループに分割します。 - +LINQ クエリ式で入れ子になったグループを作成する方法を次の例に示します。 学年レベルに基づいて作成した各グループを、さらに個人の名前に基づくグループに分割します。 + ## 例 - > [!NOTE] - > この例には、「[オブジェクトのコレクションの照会](query-a-collection-of-objects.md)」のサンプル コードで定義されているオブジェクトへの参照が含まれています。 +> [!NOTE] +> この例には、「[オブジェクトのコレクションの照会](query-a-collection-of-objects.md)」のサンプル コードで定義されているオブジェクトへの参照が含まれています。 + +[!code-csharp[csProgGuideLINQ#24](~/samples/snippets/csharp/concepts/linq/how-to-create-a-nested-group_1.cs)] + +入れ子になったグループの内部要素に対して反復処理を実行するために、入れ子になった `foreach` ループが 3 つ必要であることに注意してください。 + +## 関連項目 - [!code-csharp[csProgGuideLINQ#24](../../../samples/snippets/csharp/concepts/linq/how-to-create-a-nested-group_1.cs)] - - 入れ子になったグループの内部要素に対して反復処理を実行するために、入れ子になった `foreach` ループが 3 つ必要であることに注意してください。 - -## 関連項目 - [LINQ クエリ式](index.md) +[統合言語クエリ (LINQ)](index.md) diff --git a/docs/csharp/linq/dynamically-specify-predicate-filters-at-runtime.md b/docs/csharp/linq/dynamically-specify-predicate-filters-at-runtime.md index 5c4eb56af0e..4a399521c92 100644 --- a/docs/csharp/linq/dynamically-specify-predicate-filters-at-runtime.md +++ b/docs/csharp/linq/dynamically-specify-predicate-filters-at-runtime.md @@ -1,74 +1,74 @@ --- -title: 実行時における述語フィルターの動的指定 -description: 実行時に述語フィルターを動的に指定する方法 -ms.date: 12/1/2016 -ms.assetid: 90238470-0767-497c-916c-52d0d16845e0 -ms.openlocfilehash: fa3426a513758d8c30bf381ec480b9b8d12a5f81 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33287941" +title: 実行時における述語フィルターの動的指定 (C# での LINQ) +description: C# で LINQ を使用して、実行時に述語フィルターを動的に指定する方法について説明します。 +ms.date: 12/1/2016 +ms.assetid: 90238470-0767-497c-916c-52d0d16845e0 +ms.openlocfilehash: 7051d7c754a0db29771a2e03a3b624c0e434eecd +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404091" --- # 実行時における述語フィルターの動的指定 -`where` 句のソース要素に適用しなければならない述語の数が実行時までわからない場合があります。 複数の述語フィルターを動的に指定する方法として、次の例のように、 メソッドを使用する方法があります。 この例は 2 段階構築になっています。 最初に、プログラムで提供される値にフィルターを適用してプログラムを実行します。 次に、実行時に提供された入力を利用してプログラムをもう一度実行します。 - -## Contains メソッドを使用してフィルター処理するには - -1. 新しいコンソール アプリケーションを開き、それに `PredicateFilters` という名前を付けます。 - -2. 「[オブジェクトのコレクションを照会する](query-a-collection-of-objects.md)」から `StudentClass` クラスをコピーし、クラス `Program` の下の名前空間 `PredicateFilters` に貼り付けます。 `StudentClass` は、`Student` オブジェクトの一覧を提供します。 - -3. `StudentClass` で `Main` メソッドをコメント アウトします。 - -4. クラス `Program` を次のコードで置き換えます。 - - [!code-csharp[csProgGuideLINQ#26](../../../samples/snippets/csharp/concepts/linq/how-to-dynamically-specify-predicate-filters-at-runtime_1.cs)] - -5. 次の行をクラス `DynamicPredicates` の `Main` メソッドに追加します。`ids` の宣言の下です。 - +`where` 句のソース要素に適用しなければならない述語の数が実行時までわからない場合があります。 複数の述語フィルターを動的に指定する方法として、次の例のように、 メソッドを使用する方法があります。 この例は 2 段階構築になっています。 最初に、プログラムで提供される値にフィルターを適用してプログラムを実行します。 次に、実行時に提供された入力を利用してプログラムをもう一度実行します。 + +## Contains メソッドを使用してフィルター処理するには + +1. 新しいコンソール アプリケーションを開き、それに `PredicateFilters` という名前を付けます。 + +2. 「[オブジェクトのコレクションを照会する](query-a-collection-of-objects.md)」から `StudentClass` クラスをコピーし、クラス `Program` の下の名前空間 `PredicateFilters` に貼り付けます。 `StudentClass` は、`Student` オブジェクトの一覧を提供します。 + +3. `StudentClass` で `Main` メソッドをコメント アウトします。 + +4. クラス `Program` を次のコードで置き換えます。 + + [!code-csharp[csProgGuideLINQ#26](~/samples/snippets/csharp/concepts/linq/how-to-dynamically-specify-predicate-filters-at-runtime_1.cs)] + +5. 次の行をクラス `DynamicPredicates` の `Main` メソッドに追加します。`ids` の宣言の下です。 + ```csharp QueryById(ids); ``` -6. プロジェクトを実行します。 - -7. 次の出力がコンソール ウィンドウに表示されます。 - - Garcia: 114 - - O'Donnell: 112 - - Omelchenko: 111 - -8. 次の手順はプロジェクトをもう一度実行することですが、今度は配列 `ids` の代わりに実行時に提供された入力を使用します。 `Main` メソッドで `QueryByID(ids)` を `QueryByID(args)` に変更します。 - -9. コマンド ライン引数 `122 117 120 115` でプロジェクトを実行します。 プロジェクトが実行されると、これらの値が `Main` メソッドのパラメーター、`args` の要素になります。 - -10. 次の出力がコンソール ウィンドウに表示されます。 - - Adams: 120 - - Feng: 117 - - Garcia: 115 - - Tucker: 122 - -## switch ステートメントを使用してフィルター処理するには - -1. `switch` ステートメントを使用し、あらかじめ決定されている代替クエリから選択できます。 次の例では、`studentQuery` は、実行時に指定された学年に基づき、別の `where` 句を使用します。 - -2. 次のメソッドをコピーし、クラス `DynamicPredicates` に貼り付けます。 - - [!code-csharp[csProgGuideLINQ#27](../../../samples/snippets/csharp/concepts/linq//how-to-dynamically-specify-predicate-filters-at-runtime_2.cs)] - -3. `Main` メソッドで、`QueryByID` の呼び出しを次の呼び出しに置換します。この呼び出しは、`args` 配列の最初の要素をその引数として送信します (`QueryByYear(args[0])`)。 - -4. 1 から 4 の整数をコマンド ライン引数としてプロジェクトを実行します。 - - -## 参照 - [LINQ クエリ式](index.md) - [where 句](../language-reference/keywords/where-clause.md) +6. プロジェクトを実行します。 + +7. 次の出力がコンソール ウィンドウに表示されます。 + + Garcia: 114 + + O'Donnell: 112 + + Omelchenko: 111 + +8. 次の手順はプロジェクトをもう一度実行することですが、今度は配列 `ids` の代わりに実行時に提供された入力を使用します。 `Main` メソッドで `QueryByID(ids)` を `QueryByID(args)` に変更します。 + +9. コマンド ライン引数 `122 117 120 115` でプロジェクトを実行します。 プロジェクトが実行されると、これらの値が `Main` メソッドのパラメーター、`args` の要素になります。 + +10. 次の出力がコンソール ウィンドウに表示されます。 + + Adams: 120 + + Feng: 117 + + Garcia: 115 + + Tucker: 122 + +## switch ステートメントを使用してフィルター処理するには + +1. `switch` ステートメントを使用し、あらかじめ決定されている代替クエリから選択できます。 次の例では、`studentQuery` は、実行時に指定された学年に基づき、別の `where` 句を使用します。 + +2. 次のメソッドをコピーし、クラス `DynamicPredicates` に貼り付けます。 + + [!code-csharp[csProgGuideLINQ#27](~/samples/snippets/csharp/concepts/linq//how-to-dynamically-specify-predicate-filters-at-runtime_2.cs)] + +3. `Main` メソッドで、`QueryByID` の呼び出しを次の呼び出しに置換します。この呼び出しは、`args` 配列の最初の要素をその引数として送信します (`QueryByYear(args[0])`)。 + +4. 1 から 4 の整数をコマンド ライン引数としてプロジェクトを実行します。 + +## 関連項目 + +[統合言語クエリ (LINQ)](index.md) +[where 句](../language-reference/keywords/where-clause.md) \ No newline at end of file diff --git a/docs/csharp/linq/group-query-results.md b/docs/csharp/linq/group-query-results.md index 2dce8f88392..31b6ab84f30 100644 --- a/docs/csharp/linq/group-query-results.md +++ b/docs/csharp/linq/group-query-results.md @@ -1,78 +1,86 @@ --- -title: クエリ結果のグループ化 -description: 結果をグループ化する方法です。 -ms.date: 12/1/2016 -ms.assetid: 2e4ec27f-06fb-4de7-8973-0189906d4520 -ms.openlocfilehash: cb7808bfdd86dd23882d0722b87b1e013a84141e -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 +title: クエリ結果のグループ化 (C# での LINQ) +description: C# で LINQ を使用して、結果をグループ化する方法について説明します。 +ms.date: 12/1/2016 +ms.assetid: 2e4ec27f-06fb-4de7-8973-0189906d4520 +ms.openlocfilehash: 4da0aac6b406f588ea4f241c72d5700e8a63838c +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37403866" --- # クエリ結果のグループ化 -グループ化は、LINQ の最も強力な機能の 1 つです。 次の例では、さまざまな方法でデータをグループ化する方法を示します。 - -- 1 つのプロパティで。 - -- 文字列プロパティの最初の文字で。 - -- 計算された数値の範囲で。 - -- ブール述語またはその他の式で。 - -- 複合キーで。 - - さらに、最後の 2 つのクエリは、学生の名と姓だけを含む新しい匿名型に結果を射影します。 詳しくは、「[group 句](../language-reference/keywords/group-clause.md)」をご覧ください。 - -## 例 - このトピックのすべての例では、次のヘルパー クラスとデータ ソースを使います。 - - [!code-csharp[csProgGuideLINQ#15](../../../samples/snippets/csharp/concepts/linq/how-to-group-query-results_1.cs)] - -## 例 - 次の例では、要素の 1 つのプロパティをグループ化キーとして使って、ソース要素をグループ化する方法を示します。 この場合、キーは学生の姓である `string` です。 また、キーの部分文字列を使うこともできます。 グループ化操作では、型の既定の等値比較子を使います。 - - 次のメソッドを `StudentClass` クラスに貼り付けます。 `Main` メソッドの呼び出しステートメントを `sc.GroupBySingleProperty()` に変更します。 - - [!code-csharp[csProgGuideLINQ#17](../../../samples/snippets/csharp/concepts/linq/how-to-group-query-results_2.cs)] - -## 例 - 次の例では、オブジェクトのプロパティ以外の何かをグループ化キーとして使って、ソース要素をグループ化する方法を示します。 この例では、キーは学生の姓の最初の文字です。 - - 次のメソッドを `StudentClass` クラスに貼り付けます。 `Main` メソッドの呼び出しステートメントを `sc.GroupBySubstring()` に変更します。 - - [!code-csharp[csProgGuideLINQ#18](../../../samples/snippets/csharp/concepts/linq/how-to-group-query-results_3.cs)] - -## 例 - 次の例では、数値範囲をグループ化キーとして使って、ソース要素をグループ化する方法を示します。 クエリは、名と姓および学生が属しているパーセンタイル範囲のみを含む匿名型に、結果を投影します。 匿名型を使っているのは、結果を表示するために完全な `Student` オブジェクトを使う必要がないためです。 `GetPercentile` は、学生の平均スコアに基づいてパーセンタイルを計算するヘルパー関数です。 メソッドは、0 から 10 の間の整数を返します。 - - [!code-csharp[csProgGuideLINQ#50](../../../samples/snippets/csharp/concepts/linq/how-to-group-query-results_4.cs)] - - 次のメソッドを `StudentClass` クラスに貼り付けます。 `Main` メソッドの呼び出しステートメントを `sc.GroupByRange()` に変更します。 - - [!code-csharp[csProgGuideLINQ#19](../../../samples/snippets/csharp/concepts/linq/how-to-group-query-results_5.cs)] - -## 例 - 次の例では、ブール比較式を使って、ソース要素をグループ化する方法を示します。 この例のブール式は、学生の平均試験スコアが 75 より大きいかどうかをテストします。 前の例と同じように、完全なソース要素が必要ないため、結果を匿名型に投影します。 匿名型のプロパティは `Key` メンバーのプロパティになり、クエリ実行時に名前でアクセスできることに注意してください。 - - 次のメソッドを `StudentClass` クラスに貼り付けます。 `Main` メソッドの呼び出しステートメントを `sc.GroupByBoolean()` に変更します。 - - [!code-csharp[csProgGuideLINQ#20](../../../samples/snippets/csharp/concepts/linq/how-to-group-query-results_6.cs)] - -## 例 - 次の例では、匿名型を使って、複数の値を含むキーをカプセル化する方法を示します。 この例では、最初のキーの値は学生の姓の最初の文字です。 2 番目のキーの値は、最初の試験での学生のスコアが 85 より高いかどうかを示すブール値です。 キーの任意のプロパティでグループを並べ替えることができます。 - - 次のメソッドを `StudentClass` クラスに貼り付けます。 `Main` メソッドの呼び出しステートメントを `sc.GroupByCompositeKey()` に変更します。 - - [!code-csharp[csProgGuideLINQ#21](../../../samples/snippets/csharp/concepts/linq/how-to-group-query-results_7.cs)] - -## 関連項目 - - - [LINQ クエリ式](index.md) - [group 句](../language-reference/keywords/group-clause.md) - [匿名型](../programming-guide/classes-and-structs/anonymous-types.md) - [グループ化操作でのサブクエリの実行](perform-a-subquery-on-a-grouping-operation.md) - [入れ子になったグループの作成](create-a-nested-group.md) - [データのグループ化](../programming-guide/concepts/linq/grouping-data.md) +グループ化は、LINQ の最も強力な機能の 1 つです。 次の例では、さまざまな方法でデータをグループ化する方法を示します。 + +- 1 つのプロパティで。 + +- 文字列プロパティの最初の文字で。 + +- 計算された数値の範囲で。 + +- ブール述語またはその他の式で。 + +- 複合キーで。 + +さらに、最後の 2 つのクエリは、学生の名と姓だけを含む新しい匿名型に結果を射影します。 詳しくは、「[group 句](../language-reference/keywords/group-clause.md)」をご覧ください。 + +## 例 + +このトピックのすべての例では、次のヘルパー クラスとデータ ソースを使います。 + +[!code-csharp[csProgGuideLINQ#15](~/samples/snippets/csharp/concepts/linq/how-to-group-query-results_1.cs)] + +## 例 + +次の例では、要素の 1 つのプロパティをグループ化キーとして使って、ソース要素をグループ化する方法を示します。 この場合、キーは学生の姓である `string` です。 また、キーの部分文字列を使うこともできます。 グループ化操作では、型の既定の等値比較子を使います。 + +次のメソッドを `StudentClass` クラスに貼り付けます。 `Main` メソッドの呼び出しステートメントを `sc.GroupBySingleProperty()` に変更します。 + +[!code-csharp[csProgGuideLINQ#17](~/samples/snippets/csharp/concepts/linq/how-to-group-query-results_2.cs)] + +## 例 + +次の例では、オブジェクトのプロパティ以外の何かをグループ化キーとして使って、ソース要素をグループ化する方法を示します。 この例では、キーは学生の姓の最初の文字です。 + +次のメソッドを `StudentClass` クラスに貼り付けます。 `Main` メソッドの呼び出しステートメントを `sc.GroupBySubstring()` に変更します。 + +[!code-csharp[csProgGuideLINQ#18](~/samples/snippets/csharp/concepts/linq/how-to-group-query-results_3.cs)] + +## 例 + +次の例では、数値範囲をグループ化キーとして使って、ソース要素をグループ化する方法を示します。 クエリは、名と姓および学生が属しているパーセンタイル範囲のみを含む匿名型に、結果を投影します。 匿名型を使っているのは、結果を表示するために完全な `Student` オブジェクトを使う必要がないためです。 `GetPercentile` は、学生の平均スコアに基づいてパーセンタイルを計算するヘルパー関数です。 メソッドは、0 から 10 の間の整数を返します。 + +[!code-csharp[csProgGuideLINQ#50](~/samples/snippets/csharp/concepts/linq/how-to-group-query-results_4.cs)] + +次のメソッドを `StudentClass` クラスに貼り付けます。 `Main` メソッドの呼び出しステートメントを `sc.GroupByRange()` に変更します。 + +[!code-csharp[csProgGuideLINQ#19](~/samples/snippets/csharp/concepts/linq/how-to-group-query-results_5.cs)] + +## 例 + +次の例では、ブール比較式を使って、ソース要素をグループ化する方法を示します。 この例のブール式は、学生の平均試験スコアが 75 より大きいかどうかをテストします。 前の例と同じように、完全なソース要素が必要ないため、結果を匿名型に投影します。 匿名型のプロパティは `Key` メンバーのプロパティになり、クエリ実行時に名前でアクセスできることに注意してください。 + +次のメソッドを `StudentClass` クラスに貼り付けます。 `Main` メソッドの呼び出しステートメントを `sc.GroupByBoolean()` に変更します。 + +[!code-csharp[csProgGuideLINQ#20](~/samples/snippets/csharp/concepts/linq/how-to-group-query-results_6.cs)] + +## 例 + +次の例では、匿名型を使って、複数の値を含むキーをカプセル化する方法を示します。 この例では、最初のキーの値は学生の姓の最初の文字です。 2 番目のキーの値は、最初の試験での学生のスコアが 85 より高いかどうかを示すブール値です。 キーの任意のプロパティでグループを並べ替えることができます。 + +次のメソッドを `StudentClass` クラスに貼り付けます。 `Main` メソッドの呼び出しステートメントを `sc.GroupByCompositeKey()` に変更します。 + +[!code-csharp[csProgGuideLINQ#21](~/samples/snippets/csharp/concepts/linq/how-to-group-query-results_7.cs)] + +## 関連項目 + + + +[統合言語クエリ (LINQ)](index.md) +[group 句](../language-reference/keywords/group-clause.md) +[匿名型](../programming-guide/classes-and-structs/anonymous-types.md) +[グループ化操作でのサブクエリの実行](perform-a-subquery-on-a-grouping-operation.md) +[入れ子になったグループの作成](create-a-nested-group.md) +[データのグループ化](../programming-guide/concepts/linq/grouping-data.md) \ No newline at end of file diff --git a/docs/csharp/linq/group-results-by-contiguous-keys.md b/docs/csharp/linq/group-results-by-contiguous-keys.md index adcae52f1f8..265ec31a857 100644 --- a/docs/csharp/linq/group-results-by-contiguous-keys.md +++ b/docs/csharp/linq/group-results-by-contiguous-keys.md @@ -1,53 +1,54 @@ --- -title: 連続するキーで結果をグループ化する -description: 連続するキーで結果をグループ化する方法。 -ms.date: 12/1/2016 -ms.assetid: cbda9c08-151b-4c9e-82f7-c3d7f3dac66b -ms.openlocfilehash: a8d6ac133932a12154d5b23454065144c7652067 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33281438" +title: 連続するキーで結果をグループ化する (C# での LINQ) +description: C# で LINQ を使用して、連続するキーで結果をグループ化する方法について説明します。 +ms.date: 12/1/2016 +ms.assetid: cbda9c08-151b-4c9e-82f7-c3d7f3dac66b +ms.openlocfilehash: 8ad08d861e2d0f5ee0f8a2eceeb8d82a9aa2a5a6 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404763" --- # 連続するキーで結果をグループ化する -要素をグループ化し、連続するキーのサブシーケンスを表すチャンクにする方法を次の例に示します。 たとえば、次の一連のキーと値のペアがあるとします。 - -|キー|[値]| -|---------|-----------| -|A|水| -|A|think| -|A|that| -|B|Linq| -|C|is| -|A|really| -|B|cool| -|B|!| - - 次のグループがこの順序で作成されます。 - -1. We, think, that - -2. Linq - -3. is - -4. really - -5. cool, ! - - ソリューションは、結果をストリーミングで返すスレッド セーフな拡張メソッドとして実装されます。 つまり、ソース シーケンス内を移動するときにグループが作成されます。 `group` 演算子や `orderby` 演算子とは異なり、すべてのシーケンスの読み取りが終わる前に、呼び出し元にグループを返し始めることができます。 - - ソース コードのコメントで説明されているように、ソース シーケンスが反復処理されるときに各グループまたはチャンクのコピーを作成することで、スレッド セーフが実現されます。 ソース シーケンスに連続するアイテムの大きなシーケンスがある場合、共通言語ランタイムにより がスローされる可能性があります。 - -## 例 - 拡張メソッドと、それを使用するクライアント コードを次の例に示します。 - - [!code-csharp[cscsrefContiguousGroups#1](../../../samples/snippets/csharp/concepts/linq/how-to-group-results-by-contiguous-keys_1.cs)] - - プロジェクトで拡張メソッドを使用するには、`MyExtensions` 静的クラスを新規または既存のソース コード ファイルにコピーし、必要に応じて、配置されている名前空間の `using` ディレクティブを追加します。 - -## 関連項目 - [LINQ クエリ式](index.md) - +要素をグループ化し、連続するキーのサブシーケンスを表すチャンクにする方法を次の例に示します。 たとえば、次の一連のキーと値のペアがあるとします。 + +|キー|[値]| +|---------|-----------| +|A|水| +|A|think| +|A|that| +|B|Linq| +|C|is| +|A|really| +|B|cool| +|B|!| + +次のグループがこの順序で作成されます。 + +1. We, think, that + +2. Linq + +3. is + +4. really + +5. cool, ! + +ソリューションは、結果をストリーミングで返すスレッド セーフな拡張メソッドとして実装されます。 つまり、ソース シーケンス内を移動するときにグループが作成されます。 `group` 演算子や `orderby` 演算子とは異なり、すべてのシーケンスの読み取りが終わる前に、呼び出し元にグループを返し始めることができます。 + +ソース コードのコメントで説明されているように、ソース シーケンスが反復処理されるときに各グループまたはチャンクのコピーを作成することで、スレッド セーフが実現されます。 ソース シーケンスに連続するアイテムの大きなシーケンスがある場合、共通言語ランタイムにより がスローされる可能性があります。 + +## 例 + +拡張メソッドと、それを使用するクライアント コードの両方を次の例に示します。 + +[!code-csharp[cscsrefContiguousGroups#1](~/samples/snippets/csharp/concepts/linq/how-to-group-results-by-contiguous-keys_1.cs)] + +プロジェクトで拡張メソッドを使用するには、`MyExtensions` 静的クラスを新規または既存のソース コード ファイルにコピーし、必要に応じて、配置されている名前空間の `using` ディレクティブを追加します。 + +## 関連項目 + +[統合言語クエリ (LINQ)](index.md) \ No newline at end of file diff --git a/docs/csharp/linq/handle-exceptions-in-query-expressions.md b/docs/csharp/linq/handle-exceptions-in-query-expressions.md index 9bc5c6cec19..81a630080b3 100644 --- a/docs/csharp/linq/handle-exceptions-in-query-expressions.md +++ b/docs/csharp/linq/handle-exceptions-in-query-expressions.md @@ -1,35 +1,35 @@ --- -title: クエリ式の例外の処理 -description: クエリ式の例外を処理する方法。 -ms.date: 12/1/2016 -ms.assetid: 2bf0c397-13fb-4f68-bc2b-531c6c88a167 -ms.openlocfilehash: 691373fabeb3934ecc454cbc3b36a5f7bf477bee -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33284852" +title: クエリ式の例外の処理 (C# での LINQ) +description: C# で LINQ クエリ式の例外を処理する方法について説明します。 +ms.date: 12/1/2016 +ms.assetid: 2bf0c397-13fb-4f68-bc2b-531c6c88a167 +ms.openlocfilehash: 344d11129814516a5ed3dcf0eba73a5ecbb96981 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37403840" --- # クエリ式の例外の処理 -クエリ式のコンテキストで任意のメソッドを呼び出すことができます。 ただし、データ ソースのコンテンツが変更されたり例外がスローされたりするなどの副作用が生じる可能性のあるクエリ式では、メソッドを呼び出さないようにすることをお勧めします。 この例では、クエリ式でメソッドを呼び出すときに、例外処理に関する .NET Framework の全般的なガイドラインに違反することなく例外の発生を避ける方法を示します。 ガイドラインでは、特定のコンテキストで特定の例外がスローされる理由がわかっているときにその例外をキャッチすることは認められています。 詳細については、「[例外の推奨事項](../../standard/exceptions/best-practices-for-exceptions.md)」を参照してください。 - - 最後の例では、クエリの実行中に例外をスローする必要がある場合の処理方法を示します。 - -## 例 - - 次の例では、例外処理コードをクエリ式の外側に移動する方法を説明します。 この方法は、メソッドがクエリのローカル変数に依存しない場合にのみ可能です。 - - [!code-csharp[csProgGuideLINQ#10](../../../samples/snippets/csharp/concepts/linq/how-to-handle-exceptions-in-query-expressions_1.cs)] - -## 例 - - 場合によっては、クエリ内からスローされる例外に対する最適な応答は、クエリの実行をすぐに停止することです。 次の例では、クエリ本体の内部からスローされる例外を処理する方法を示します。 `SomeMethodThatMightThrow` で、クエリの実行を停止することが必要な例外が発生する可能性があるとします。 - - `try` ブロックは `foreach` ループを囲み、クエリ自体を囲むのではありません。 その理由は、`foreach` ループがクエリの実際の実行ポイントであるためです。 詳細については、「[LINQ クエリの概要](../programming-guide/concepts/linq/introduction-to-linq-queries.md)」を参照してください。 - - [!code-csharp[csProgGuideLINQ#12](../../../samples/snippets/csharp/concepts/linq/how-to-handle-exceptions-in-query-expressions_2.cs)] - - -## 参照 - [LINQ クエリ式](index.md) +クエリ式のコンテキストで任意のメソッドを呼び出すことができます。 ただし、データ ソースのコンテンツが変更されたり例外がスローされたりするなどの副作用が生じる可能性のあるクエリ式では、メソッドを呼び出さないようにすることをお勧めします。 この例では、クエリ式でメソッドを呼び出すときに、例外処理に関する .NET の全般的なガイドラインに違反することなく例外の発生を避ける方法を示します。 ガイドラインでは、特定のコンテキストで特定の例外がスローされる理由がわかっているときにその例外をキャッチすることは認められています。 詳細については、「[例外の推奨事項](../../standard/exceptions/best-practices-for-exceptions.md)」を参照してください。 + +最後の例では、クエリの実行中に例外をスローする必要がある場合の処理方法を示します。 + +## 例 + +次の例では、例外処理コードをクエリ式の外側に移動する方法を説明します。 この方法は、メソッドがクエリのローカル変数に依存しない場合にのみ可能です。 + +[!code-csharp[csProgGuideLINQ#10](~/samples/snippets/csharp/concepts/linq/how-to-handle-exceptions-in-query-expressions_1.cs)] + +## 例 + +場合によっては、クエリ内からスローされる例外に対する最適な応答は、クエリの実行をすぐに停止することです。 次の例では、クエリ本体の内部からスローされる例外を処理する方法を示します。 `SomeMethodThatMightThrow` で、クエリの実行を停止することが必要な例外が発生する可能性があるとします。 + +`try` ブロックは `foreach` ループを囲み、クエリ自体を囲むのではありません。 その理由は、`foreach` ループがクエリの実際の実行ポイントであるためです。 詳細については、「[LINQ クエリの概要](../programming-guide/concepts/linq/introduction-to-linq-queries.md)」を参照してください。 + +[!code-csharp[csProgGuideLINQ#12](~/samples/snippets/csharp/concepts/linq/how-to-handle-exceptions-in-query-expressions_2.cs)] + +## 関連項目 + +[統合言語クエリ (LINQ)](index.md) diff --git a/docs/csharp/linq/handle-null-values-in-query-expressions.md b/docs/csharp/linq/handle-null-values-in-query-expressions.md index cf6f92da09a..02df57f1a6d 100644 --- a/docs/csharp/linq/handle-null-values-in-query-expressions.md +++ b/docs/csharp/linq/handle-null-values-in-query-expressions.md @@ -1,34 +1,35 @@ --- -title: クエリ式の null 値の処理 -description: クエリ式の null 値を処理する方法。 -ms.date: 12/1/2016 -ms.assetid: ac63ae8b-724d-4251-9334-528f4e884ae7 -ms.openlocfilehash: ecd174462ef51a6dd7b7696abb9e111fc32d9ec7 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33272388" +title: クエリ式の null 値の処理 (C# での LINQ) +description: C# の LINQ クエリ式で null 値を処理する方法について説明します。 +ms.date: 12/1/2016 +ms.assetid: ac63ae8b-724d-4251-9334-528f4e884ae7 +ms.openlocfilehash: 34cda0be5fa38422415b6c3927f40a0df95fc6a6 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404104" --- # クエリ式の null 値の処理 -この例では、ソース コレクション内の可能な null 値を処理する方法を示します。 のようなオブジェクト コレクションには、値が [null](../language-reference/keywords/null.md) の要素を含めることができます。 ソース コレクションが null であるか null の値を持つ要素を含み、クエリで null 値を処理しない場合、クエリを実行すると がスローされます。 - +この例では、ソース コレクション内の可能な null 値を処理する方法を示します。 のようなオブジェクト コレクションには、値が [null](../language-reference/keywords/null.md) の要素を含めることができます。 ソース コレクションが null であるか null の値を持つ要素を含み、クエリで null 値を処理しない場合、クエリを実行すると がスローされます。 + ## 例 - 次の例に示すように、null 参照の例外を回避する防御的なコーディングをすることができます。 - - [!code-csharp[csProgGuideLINQ#82](../../../samples/snippets/csharp/concepts/linq/how-to-handle-null-values-in-query-expressions_1.cs)] - - 前の例では、`where` 句によって、カテゴリ シーケンス内のすべての null 要素が除外されます。 この手法は、join 句での null チェックに依存しません。 この例の null 条件式が機能する理由は、`Products.CategoryID` が `int?` 型 (`Nullable` の短縮形) であるためです。 - +次の例に示すように、null 参照の例外を回避する防御的なコーディングをすることができます。 + +[!code-csharp[csProgGuideLINQ#82](~/samples/snippets/csharp/concepts/linq/how-to-handle-null-values-in-query-expressions_1.cs)] + +前の例では、`where` 句によって、カテゴリ シーケンス内のすべての null 要素が除外されます。 この手法は、join 句での null チェックに依存しません。 この例の null 条件式が機能する理由は、`Products.CategoryID` が `int?` 型 (`Nullable` の短縮形) であるためです。 + ## 例 - join 句で、比較キーの一方だけが null 許容値型である場合、クエリ式でもう一方のキーを null 許容型にキャストできます。 次の例では、`EmployeeID` は `int?` 型の値を含む列であるとします。 - - [!code-csharp[csProgGuideLINQ#83](../../../samples/snippets/csharp/concepts/linq/how-to-handle-null-values-in-query-expressions_2.cs)] - -## 関連項目 - - [LINQ クエリ式](index.md) - [Null 許容型](../programming-guide/nullable-types/index.md) +join 句で、比較キーの一方だけが null 許容値型である場合、クエリ式でもう一方のキーを null 許容型にキャストできます。 次の例では、`EmployeeID` は `int?` 型の値を含む列であるとします。 + +[!code-csharp[csProgGuideLINQ#83](~/samples/snippets/csharp/concepts/linq/how-to-handle-null-values-in-query-expressions_2.cs)] + +## 関連項目 + + +[統合言語クエリ (LINQ)](index.md) +[Null 許容型](../programming-guide/nullable-types/index.md) diff --git a/docs/csharp/linq/join-by-using-composite-keys.md b/docs/csharp/linq/join-by-using-composite-keys.md index 04be0862ef0..0607647c217 100644 --- a/docs/csharp/linq/join-by-using-composite-keys.md +++ b/docs/csharp/linq/join-by-using-composite-keys.md @@ -1,41 +1,43 @@ --- -title: 複合キーを使用した結合 -description: 複合キーを使用して結合する方法。 -ms.date: 12/1/2016 -ms.assetid: da70b54d-3213-45eb-8437-fbe75cbcf935 -ms.openlocfilehash: e40f4d147886c07913c761bb5df83ee34d23eaba -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33271215" +title: 複合キーを使用した結合 (C# での LINQ) +description: LINQ で複合キーを使用して結合する方法について説明します。 +ms.date: 12/1/2016 +ms.assetid: da70b54d-3213-45eb-8437-fbe75cbcf935 +ms.openlocfilehash: dd3f5e949b5c1bc6abc592dc135e73a91be801e9 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404029" --- # 複合キーを使用した結合 -この例では、複数のキーを使用して一致項目を定義する結合操作の実行方法を示します。 この操作は複合キーを使用して行います。 比較対象とする値を使用し、匿名型または名前付きの型として複合キーを作成します。 メソッドの境界を越えてクエリ変数が渡される場合は、キーの をオーバーライドする名前付きの型を使用してください。 各キーのプロパティ名とその出現順序は一致している必要があります。 - -## 例 - 次の例では、複合キーを使用して 3 つのテーブルのデータを結合する方法を示します。 - -```csharp -var query = from o in db.Orders - from p in db.Products - join d in db.OrderDetails - on new {o.OrderID, p.ProductID} equals new {d.OrderID, d.ProductID} into details - from d in details - select new {o.OrderID, p.ProductID, d.UnitPrice}; -``` - - 複合キーの型の推定は、キーに含まれるプロパティの名前とその出現順序によって異なります。 ソース シーケンス内のプロパティの名前が異なる場合は、キー内で新しい名前を割り当てる必要があります。 たとえば、`Orders` テーブルと `OrderDetails` テーブルの列にそれぞれ異なる名前が使用されている場合、匿名型で同じ名前を割り当てることにより、復号キーを作成できます。 - -```csharp -join...on new {Name = o.CustomerName, ID = o.CustID} equals - new {Name = d.CustName, ID = d.CustID } -``` - - 複合キーは、`group` 句でも使用できます。 - -## 関連項目 - [LINQ クエリ式](index.md) - [join 句](../language-reference/keywords/join-clause.md) - [group 句](../language-reference/keywords/group-clause.md) +この例では、複数のキーを使用して一致項目を定義する結合操作の実行方法を示します。 この操作は複合キーを使用して行います。 比較対象とする値を使用し、匿名型または名前付きの型として複合キーを作成します。 メソッドの境界を越えてクエリ変数が渡される場合は、キーの をオーバーライドする名前付きの型を使用してください。 各キーのプロパティ名とその出現順序は一致している必要があります。 + +## 例 + +次の例では、複合キーを使用して 3 つのテーブルのデータを結合する方法を示します。 + +```csharp +var query = from o in db.Orders + from p in db.Products + join d in db.OrderDetails + on new {o.OrderID, p.ProductID} equals new {d.OrderID, d.ProductID} into details + from d in details + select new {o.OrderID, p.ProductID, d.UnitPrice}; +``` + +複合キーの型の推定は、キーに含まれるプロパティの名前とその出現順序によって異なります。 ソース シーケンス内のプロパティの名前が異なる場合は、キー内で新しい名前を割り当てる必要があります。 たとえば、`Orders` テーブルと `OrderDetails` テーブルの列にそれぞれ異なる名前が使用されている場合、匿名型で同じ名前を割り当てることにより、復号キーを作成できます。 + +```csharp +join...on new {Name = o.CustomerName, ID = o.CustID} equals + new {Name = d.CustName, ID = d.CustID } +``` + +複合キーは、`group` 句でも使用できます。 + +## 関連項目 + +[統合言語クエリ (LINQ)](index.md) +[join 句](../language-reference/keywords/join-clause.md) +[group 句](../language-reference/keywords/group-clause.md) \ No newline at end of file diff --git a/docs/csharp/linq/linq-in-csharp.md b/docs/csharp/linq/linq-in-csharp.md index 7196325967e..139835172ad 100644 --- a/docs/csharp/linq/linq-in-csharp.md +++ b/docs/csharp/linq/linq-in-csharp.md @@ -1,40 +1,43 @@ --- -title: LINQ (C#) -description: LINQ について詳しく説明したトピックへのリンクを紹介しています。 -ms.date: 11/30/2016 -ms.assetid: 8eb3284f-0ab9-4cad-9216-2da58d9761a5 -ms.openlocfilehash: 8501156bf2dfeff63a99a56d6f776ee7f2e350dc -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 +title: LINQ (C#) +description: C# での LINQ について詳しく説明したトピックへのリンクを紹介しています。 +ms.date: 11/30/2016 +ms.assetid: 8eb3284f-0ab9-4cad-9216-2da58d9761a5 +ms.openlocfilehash: 2defe82f93c8961eddd2a69e78ea446e2e996c7e +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404045" --- -# LINQ (C#) -このセクションでは、LINQ について詳しく説明したトピックへのリンクを紹介しています。 - -## このセクションの内容 - [LINQ クエリの概要](../programming-guide/concepts/linq/introduction-to-linq-queries.md) - すべての言語とデータ ソースに共通する基本的な LINQ クエリ操作の 3 つの部分について説明します。 - - [LINQ とジェネリック型](../programming-guide/concepts/linq/linq-and-generic-types.md) - LINQ で使われる場合のジェネリック型の概要を説明します。 - - [LINQ によるデータ変換](../programming-guide/concepts/linq/data-transformations-with-linq.md) - クエリで取得したデータを変換するさまざまな方法について説明します。 - - [LINQ クエリ操作での型の関係](../programming-guide/concepts/linq/type-relationships-in-linq-query-operations.md) - LINQ クエリ操作の 3 つの部分において型がどのように保持および変換されるかについて説明します。 - - [LINQ でのクエリ構文とメソッド構文](../programming-guide/concepts/linq/query-syntax-and-method-syntax-in-linq.md) - LINQ クエリを表す 2 つの方法であるメソッド構文とクエリ構文を比較します。 - - [LINQ をサポートする C# の機能](../programming-guide/concepts/linq/features-that-support-linq.md) - LINQ をサポートする C# の言語構造について説明します。 - -## 関連項目 - [LINQ クエリ式](../programming-guide/linq-query-expressions/index.md) - LINQ でのクエリの概要を説明し、他のリソースへのリンクを示します。 - - [標準クエリ演算子の概要](../programming-guide/concepts/linq/standard-query-operators-overview.md) - LINQ で使われる標準的なメソッドを紹介します。 - +# LINQ (C#) # + +このセクションでは、LINQ について詳しく説明したトピックへのリンクを紹介しています。 + +## このセクションの内容 + +[LINQ クエリの概要](../programming-guide/concepts/linq/introduction-to-linq-queries.md) +すべての言語とデータ ソースに共通する基本的な LINQ クエリ操作の 3 つの部分について説明します。 + +[LINQ とジェネリック型](../programming-guide/concepts/linq/linq-and-generic-types.md) +LINQ で使われる場合のジェネリック型の概要を説明します。 + +[LINQ によるデータ変換](../programming-guide/concepts/linq/data-transformations-with-linq.md) +クエリで取得したデータを変換するさまざまな方法について説明します。 + +[LINQ クエリ操作での型の関係](../programming-guide/concepts/linq/type-relationships-in-linq-query-operations.md) +LINQ クエリ操作の 3 つの部分において型がどのように保持および変換されるかについて説明します。 + +[LINQ でのクエリ構文とメソッド構文](../programming-guide/concepts/linq/query-syntax-and-method-syntax-in-linq.md) +LINQ クエリを表す 2 つの方法であるメソッド構文とクエリ構文を比較します。 + +[LINQ をサポートする C# の機能](../programming-guide/concepts/linq/features-that-support-linq.md) +LINQ をサポートする C# の言語構造について説明します。 + +## 関連項目 + +[LINQ クエリ式](../programming-guide/linq-query-expressions/index.md) +LINQ でのクエリの概要を説明し、他のリソースへのリンクを示します。 + +[標準クエリ演算子の概要](../programming-guide/concepts/linq/standard-query-operators-overview.md) +LINQ で使われる標準的なメソッドを紹介します。 \ No newline at end of file diff --git a/docs/csharp/linq/order-the-results-of-a-join-clause.md b/docs/csharp/linq/order-the-results-of-a-join-clause.md index 08fd4d63519..fbba8405491 100644 --- a/docs/csharp/linq/order-the-results-of-a-join-clause.md +++ b/docs/csharp/linq/order-the-results-of-a-join-clause.md @@ -1,24 +1,27 @@ --- -title: join 句の結果の順序指定 -description: join 句の結果の順序を指定する方法。 -ms.date: 12/1/2016 -ms.assetid: a7458901-1201-4c25-b8d9-c04ca52e0eb9 -ms.openlocfilehash: f426152e614ed9a9c4aa41d7ba7cb8ddf1cd3063 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33269701" +title: join 句の結果の順序指定 (C# での LINQ) +description: C# で LINQ join 句の結果の順序を指定する方法について説明します。 +ms.date: 12/1/2016 +ms.assetid: a7458901-1201-4c25-b8d9-c04ca52e0eb9 +ms.openlocfilehash: e4a12b6f9b4a99decb1f64524ebe67a196084a04 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404737" --- # join 句の結果の順序指定 -この例では、結合操作の結果の順序を指定する方法を示しています。 順序付けは結合後に実行されることに注意してください。 結合の前に 1 つ以上のソース シーケンスを指定した `orderby` 句を使用することもできますが、一般にこの方法は推奨されません。 LINQ プロバイダーによっては、結合後にその順序付けを維持しない場合があります。 - -## 例 - このクエリは、グループ結合を作成した後、スコープ内に残っているカテゴリ要素に基づいてグループを並べ替えます。 匿名型初期化子の内部では、結果のシーケンス内の一致するすべての要素がサブクエリによって順序付けられます。 - - [!code-csharp[csProgGuideLINQ#81](../../../samples/snippets/csharp/concepts/linq/how-to-order-the-results-of-a-join-clause_1.cs)] - -## 関連項目 - [LINQ クエリ式](index.md) - [orderby 句](../language-reference/keywords/orderby-clause.md) - [join 句](../language-reference/keywords/join-clause.md) + +この例では、結合操作の結果の順序を指定する方法を示しています。 順序付けは結合後に実行されることに注意してください。 結合の前に 1 つ以上のソース シーケンスを指定した `orderby` 句を使用することもできますが、一般にこの方法は推奨されません。 LINQ プロバイダーによっては、結合後にその順序付けを維持しない場合があります。 + +## 例 + +このクエリは、グループ結合を作成した後、スコープ内に残っているカテゴリ要素に基づいてグループを並べ替えます。 匿名型初期化子の内部では、結果のシーケンス内の一致するすべての要素がサブクエリによって順序付けられます。 + +[!code-csharp[csProgGuideLINQ#81](~/samples/snippets/csharp/concepts/linq/how-to-order-the-results-of-a-join-clause_1.cs)] + +## 関連項目 + +[統合言語クエリ (LINQ)](index.md) +[orderby 句](../language-reference/keywords/orderby-clause.md) +[join 句](../language-reference/keywords/join-clause.md) \ No newline at end of file diff --git a/docs/csharp/linq/perform-a-subquery-on-a-grouping-operation.md b/docs/csharp/linq/perform-a-subquery-on-a-grouping-operation.md index 3f7fa448d67..8147fdf55e3 100644 --- a/docs/csharp/linq/perform-a-subquery-on-a-grouping-operation.md +++ b/docs/csharp/linq/perform-a-subquery-on-a-grouping-operation.md @@ -1,29 +1,30 @@ --- -title: グループ化操作でのサブクエリの実行 -description: グループ化操作でサブクエリを実行する方法。 -ms.date: 12/1/2016 -ms.assetid: d75a588e-9b6f-4f37-b195-f99ec8503855 -ms.openlocfilehash: 209d05c2fe8719fa9116061d199272366146f465 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33277330" +title: グループ化操作でのサブクエリの実行 (C# での LINQ) +description: C# で LINQ を使用して、グループ化操作でサブクエリを実行する方法について説明します。 +ms.date: 12/1/2016 +ms.assetid: d75a588e-9b6f-4f37-b195-f99ec8503855 +ms.openlocfilehash: 76e54cc6b29090a8464400ae6460812dd9ad86f9 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404117" --- # グループ化操作でのサブクエリの実行 -このトピックでは、ソース データを複数のグループに整理し、各グループに対して個別にサブクエリを実行するクエリを作成する方法を 2 つ紹介します。 各例の基本的な手法として、ソース要素のグループ化には、`newGroup` という名前の "*継続*" を使用し、`newGroup` に対する新しいサブクエリを生成します。 このサブクエリは、外部クエリによって作成された新しい各グループに対して実行されます。 この例では、最終出力がグループではなく、匿名型のフラットなシーケンスであることに注意してください。 +この記事では、ソース データを複数のグループに整理し、各グループに対して個別にサブクエリを実行するクエリを作成する方法を 2 つ紹介します。 各例の基本的な手法として、ソース要素のグループ化には、`newGroup` という名前の "*継続*" を使用し、`newGroup` に対する新しいサブクエリを生成します。 このサブクエリは、外部クエリによって作成された新しい各グループに対して実行されます。 この例では、最終出力がグループではなく、匿名型のフラットなシーケンスであることに注意してください。 - グループ化する方法の詳細については、「[group 句](../language-reference/keywords/group-clause.md)」を参照してください。 +グループ化する方法の詳細については、「[group 句](../language-reference/keywords/group-clause.md)」を参照してください。 - 継続の詳細については、「[into](../language-reference/keywords/into.md)」を参照してください。 次の例では、インメモリ データ構造をデータ ソースとして使用していますが、どの種類の LINQ データ ソースにも同じ原則が当てはまります。 +継続の詳細については、「[into](../language-reference/keywords/into.md)」を参照してください。 次の例では、インメモリ データ構造をデータ ソースとして使用していますが、どの種類の LINQ データ ソースにも同じ原則が当てはまります。 -## 例 +## 例 - > [!NOTE] - > この例には、「[オブジェクトのコレクションの照会](query-a-collection-of-objects.md)」のサンプル コードで定義されているオブジェクトへの参照が含まれています。 +> [!NOTE] +> この例には、「[オブジェクトのコレクションの照会](query-a-collection-of-objects.md)」のサンプル コードで定義されているオブジェクトへの参照が含まれています。 - [!code-csharp[csProgGuideLINQ#23](../../../samples/snippets/csharp/concepts/linq/how-to-perform-a-subquery-on-a-grouping-operation_1.cs)] - -## 関連項目 - [LINQ クエリ式](index.md) +[!code-csharp[csProgGuideLINQ#23](~/samples/snippets/csharp/concepts/linq/how-to-perform-a-subquery-on-a-grouping-operation_1.cs)] + +## 関連項目 + +[統合言語クエリ (LINQ)](index.md) diff --git a/docs/csharp/linq/perform-custom-join-operations.md b/docs/csharp/linq/perform-custom-join-operations.md index 658466f4694..68b7e94693f 100644 --- a/docs/csharp/linq/perform-custom-join-operations.md +++ b/docs/csharp/linq/perform-custom-join-operations.md @@ -1,45 +1,48 @@ --- -title: カスタム結合操作の実行 -description: カスタム結合操作を実行する方法。 -ms.date: 12/1/2016 -ms.assetid: 56a2a4a5-7299-497d-b3c3-23c848678911 -ms.openlocfilehash: df80f4382ad5fa96fcdc41b338cbb53a3d8e6cb9 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33288523" +title: カスタム結合操作の実行 (C# での LINQ) +description: C# でカスタムの LINQ 結合操作を実行する方法について説明します。 +ms.date: 12/1/2016 +ms.assetid: 56a2a4a5-7299-497d-b3c3-23c848678911 +ms.openlocfilehash: 09ed0a202627a07ac8958de6ac46d7dc6c2837d0 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37403971" --- # カスタム結合操作の実行 -この例では、`join` 句では実現できない結合操作を実行する方法を示しています。 クエリ式の `join` 句は、最も一般的な種類の結合操作である等結合用に限定され、また、それを目的に最適化されています。 等結合の実行時には、`join` 句を使用することで、ほとんどの場合に最適なパフォーマンスが得られます。 - - ただし、`join` 句は、次の場合には使用できません。 - -- 結合が非等値の式に基づいている場合 (非等結合)。 - -- 結合が等値または非等値の複数の式に基づいている場合。 - -- 結合操作の前に、右辺 (内部) のシーケンスに一時的な範囲変数を導入する必要がある場合。 - - 等結合ではない結合を実行するには、複数の `from` 句を使用して、各データ ソースを個別に導入することができます。 その後、`where` 句の述語式を各ソースの範囲変数に適用します。 式は、メソッド呼び出しの形式にすることもできます。 - +この例では、`join` 句では実現できない結合操作を実行する方法を示しています。 クエリ式の `join` 句は、最も一般的な種類の結合操作である等結合用に限定され、また、それを目的に最適化されています。 等結合の実行時には、`join` 句を使用することで、ほとんどの場合に最適なパフォーマンスが得られます。 + +ただし、`join` 句は、次の場合には使用できません。 + +- 結合が非等値の式に基づいている場合 (非等結合)。 + +- 結合が等値または非等値の複数の式に基づいている場合。 + +- 結合操作の前に、右辺 (内部) のシーケンスに一時的な範囲変数を導入する必要がある場合。 + + 等結合ではない結合を実行するには、複数の `from` 句を使用して、各データ ソースを個別に導入することができます。 その後、`where` 句の述語式を各ソースの範囲変数に適用します。 式は、メソッド呼び出しの形式にすることもできます。 + > [!NOTE] -> このようなカスタム結合操作を、複数の `from` 句を使用した内部コレクションへのアクセスと混同しないでください。 詳細については、「[join 句](../language-reference/keywords/join-clause.md)」を参照してください。 - -## 例 - 次の例の最初のメソッドは、単純なクロス結合を示しています。 クロス結合は、非常に大きな結果セットを生成することがあるので、注意して使用する必要があります。 ただし、追加のクエリの実行対象となるソース シーケンスを作成するためのいくつかのシナリオでは便利な場合があります。 - - 2 番目のメソッドは、左辺のカテゴリの一覧にカテゴリ ID が含まれているすべての製品のシーケンスを生成します。 `let` 句と `Contains` メソッドを使用して一時配列を作成していることに注意してください。 クエリの前に配列を作成し、最初の `from` 句を削除することもできます。 - - [!code-csharp[csProgGuideLINQ#64](../../../samples/snippets/csharp/concepts/linq/how-to-perform-custom-join-operations_1.cs)] - -## 例 - 次の例では、クエリは一致するキーに基づいて 2 つのシーケンスを結合する必要があります。内部 (右辺) シーケンスでは、join 句自体より前にキーを取得することはできません。 この結合が `join` 句を使用して実行された場合は、要素ごとに `Split` メソッドを呼び出す必要があります。 複数の `from` 句を使用すると、クエリは、メソッドを繰り返し呼び出すことのオーバーヘッドを回避することができます。 ただし、`join` は最適化されるため、この特定の場合には、複数の `from` 句を使用するよりも処理が速くなることがあります。 結果は、主に、メソッド呼び出しにかかる負荷に応じて異なります。 - - [!code-csharp[csProgGuideLINQ#13](../../../samples/snippets/csharp/concepts/linq/how-to-perform-custom-join-operations_2.cs)] - -## 関連項目 - [LINQ クエリ式](index.md) - [join 句](../language-reference/keywords/join-clause.md) - [join 句の結果の順序指定](order-the-results-of-a-join-clause.md) +> このようなカスタム結合操作を、複数の `from` 句を使用した内部コレクションへのアクセスと混同しないでください。 詳細については、「[join 句](../language-reference/keywords/join-clause.md)」を参照してください。 + +## 例 + +次の例の最初のメソッドは、単純なクロス結合を示しています。 クロス結合は、非常に大きな結果セットを生成することがあるので、注意して使用する必要があります。 ただし、追加のクエリの実行対象となるソース シーケンスを作成するためのいくつかのシナリオでは便利な場合があります。 + +2 番目のメソッドは、左辺のカテゴリの一覧にカテゴリ ID が含まれているすべての製品のシーケンスを生成します。 `let` 句と `Contains` メソッドを使用して一時配列を作成していることに注意してください。 クエリの前に配列を作成し、最初の `from` 句を削除することもできます。 + +[!code-csharp[csProgGuideLINQ#64](~/samples/snippets/csharp/concepts/linq/how-to-perform-custom-join-operations_1.cs)] + +## 例 + +次の例では、クエリは一致するキーに基づいて 2 つのシーケンスを結合する必要があります。内部 (右辺) シーケンスでは、join 句自体より前にキーを取得することはできません。 この結合が `join` 句を使用して実行された場合は、要素ごとに `Split` メソッドを呼び出す必要があります。 複数の `from` 句を使用すると、クエリは、メソッドを繰り返し呼び出すことのオーバーヘッドを回避することができます。 ただし、`join` は最適化されるため、この特定の場合には、複数の `from` 句を使用するよりも処理が速くなることがあります。 結果は、主に、メソッド呼び出しにかかる負荷に応じて異なります。 + +[!code-csharp[csProgGuideLINQ#13](~/samples/snippets/csharp/concepts/linq/how-to-perform-custom-join-operations_2.cs)] + +## 関連項目 + +[統合言語クエリ (LINQ)](index.md) +[join 句](../language-reference/keywords/join-clause.md) +[join 句の結果の順序指定](order-the-results-of-a-join-clause.md) \ No newline at end of file diff --git a/docs/csharp/linq/perform-grouped-joins.md b/docs/csharp/linq/perform-grouped-joins.md index a5cdfd61a85..66d7bd5fdf6 100644 --- a/docs/csharp/linq/perform-grouped-joins.md +++ b/docs/csharp/linq/perform-grouped-joins.md @@ -1,44 +1,42 @@ --- -title: グループ結合の実行 -description: グループ結合を実行する方法。 -ms.date: 12/1/2016 -ms.assetid: 9667daf9-a5fd-4b43-a5c4-a9c2b744000e -ms.openlocfilehash: fbdb1a69fa2f3b171935fa3a58cf9a045be0a494 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33288178" +title: グループ結合の実行 (C# での LINQ) +description: C# で LINQ を使用して、グループ結合を実行する方法について説明します。 +ms.date: 12/1/2016 +ms.assetid: 9667daf9-a5fd-4b43-a5c4-a9c2b744000e +ms.openlocfilehash: d52aa8f75a1868c26f6a965553bf8047518bb447 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404003" --- # グループ結合の実行 -グループ結合は、階層データ構造を作成する場合に便利です。 これは、最初のコレクションの各要素と、2 番目のコレクションの相関関係を持つ要素のセットを組み合わせたものです。 - - たとえば、`Student` という名前のクラスまたはリレーショナル データベース テーブルに、`Id` と `Name` という 2 つのフィールドが含まれているとします。 `Course` という名前の 2 番目のクラスまたはリレーショナル データベース テーブルには、`StudentId` と `CourseTitle` という 2 つのフィールドが含まれているとします。 この 2 つのデータ ソースのグループ結合は、`Student.Id` と `Course.StudentId` の一致に基づいて、`Course` オブジェクトのコレクションを持つ各 `Student` をグループ化します (コレクションは空の場合もあります)。 - +グループ結合は、階層データ構造を作成する場合に便利です。 これは、最初のコレクションの各要素と、2 番目のコレクションの相関関係を持つ要素のセットを組み合わせたものです。 + +たとえば、`Student` という名前のクラスまたはリレーショナル データベース テーブルに、`Id` と `Name` という 2 つのフィールドが含まれているとします。 `Course` という名前の 2 番目のクラスまたはリレーショナル データベース テーブルには、`StudentId` と `CourseTitle` という 2 つのフィールドが含まれているとします。 この 2 つのデータ ソースのグループ結合は、`Student.Id` と `Course.StudentId` の一致に基づいて、`Course` オブジェクトのコレクションを持つ各 `Student` をグループ化します (コレクションは空の場合もあります)。 + > [!NOTE] -> 最初のコレクションの各要素は、2 番目のコレクションに相関関係を持つ要素があるかどうかにかかわらず、グループ結合の結果セットに表示されます。 相関関係を持つ要素が見つからない場合、その要素の相関関係を持つ要素のシーケンスは空です。 そのため、結果セレクターは最初のコレクションのすべての要素にアクセスできます。 これは、非グループ結合の結果セレクターとは異なります。非グループ結合の結果セレクターは、2 番目のコレクションに一致するものがない最初のコレクションの要素にアクセスすることはできません。 - - このトピックの最初の例では、グループ結合を実行する方法を示します。 2 つ目の例では、グループ結合を使用して XML 要素を作成する方法を示します。 - -## 例 - -### グループ結合の例 - 次の例では、`Pet.Owner` プロパティと一致する `Person` に基づいて、`Person` 型と `Pet` 型のオブジェクトのグループ結合を実行します。 一致ごとに要素のペアを生成する非グループ結合と異なり、グループ結合は最初のコレクションの要素ごとに 1 つのオブジェクト (この例では `Person` オブジェクト) のみを作成します。 2 番目のコレクションの対応する要素 (この例では `Pet` オブジェクト) が 1 つのコレクションにグループ化されます。 最後に、結果セレクター機能により、`Person.FirstName` と、`Pet` オブジェクトのコレクションで構成される一致ごとに匿名型が作成されます。 - - [!code-csharp[CsLINQProgJoining#5](../../../samples/snippets/csharp/concepts/linq/how-to-perform-grouped-joins_1.cs)] - -## 例 - -### XML を作成するグループ結合の例 - グループ結合は、LINQ to XML を使用した XML の作成に適しています。 次の例は前の例に似ていますが、匿名型を作成するのではなく、結果セレクター機能により、結合されたオブジェクトを表す XML 要素を作成する点が異なります。 - - [!code-csharp[CsLINQProgJoining#6](../../../samples/snippets/csharp/concepts/linq/how-to-perform-grouped-joins_2.cs)] - -## 関連項目 - - - [内部結合の実行](perform-inner-joins.md) - [左外部結合の実行](perform-left-outer-joins.md) - [匿名型](../programming-guide/classes-and-structs/anonymous-types.md) - +> 最初のコレクションの各要素は、2 番目のコレクションに相関関係を持つ要素があるかどうかにかかわらず、グループ結合の結果セットに表示されます。 相関関係を持つ要素が見つからない場合、その要素の相関関係を持つ要素のシーケンスは空です。 そのため、結果セレクターは最初のコレクションのすべての要素にアクセスできます。 これは、非グループ結合の結果セレクターとは異なります。非グループ結合の結果セレクターは、2 番目のコレクションに一致するものがない最初のコレクションの要素にアクセスすることはできません。 + +この記事の最初の例では、グループ結合を実行する方法を示します。 2 つ目の例では、グループ結合を使用して XML 要素を作成する方法を示します。 + +## 例 - グループ結合 + +次の例では、`Pet.Owner` プロパティと一致する `Person` に基づいて、`Person` 型と `Pet` 型のオブジェクトのグループ結合を実行します。 一致ごとに要素のペアを生成する非グループ結合と異なり、グループ結合は最初のコレクションの要素ごとに 1 つのオブジェクト (この例では `Person` オブジェクト) のみを作成します。 2 番目のコレクションの対応する要素 (この例では `Pet` オブジェクト) が 1 つのコレクションにグループ化されます。 最後に、結果セレクター機能により、`Person.FirstName` と、`Pet` オブジェクトのコレクションで構成される一致ごとに匿名型が作成されます。 + +[!code-csharp[CsLINQProgJoining#5](~/samples/snippets/csharp/concepts/linq/how-to-perform-grouped-joins_1.cs)] + +## 例 - XML を作成するグループ結合 + +グループ結合は、LINQ to XML を使用した XML の作成に適しています。 次の例は前の例に似ていますが、匿名型を作成するのではなく、結果セレクター機能により、結合されたオブジェクトを表す XML 要素を作成する点が異なります。 + +[!code-csharp[CsLINQProgJoining#6](~/samples/snippets/csharp/concepts/linq/how-to-perform-grouped-joins_2.cs)] + +## 関連項目 + + + +[内部結合の実行](perform-inner-joins.md) +[左外部結合の実行](perform-left-outer-joins.md) +[匿名型](../programming-guide/classes-and-structs/anonymous-types.md) \ No newline at end of file diff --git a/docs/csharp/linq/perform-inner-joins.md b/docs/csharp/linq/perform-inner-joins.md index a1f22661386..0b0c6a805ac 100644 --- a/docs/csharp/linq/perform-inner-joins.md +++ b/docs/csharp/linq/perform-inner-joins.md @@ -1,77 +1,73 @@ --- -title: 内部結合の実行 -description: 内部結合を実行する方法。 -ms.date: 12/1/2016 -ms.assetid: 45bceed6-f549-4114-a9b1-b44feb497742 -ms.openlocfilehash: 9d372579e3c32964c588b6387b6d4e97f632a21f -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33289075" +title: 内部結合の実行 (C# での LINQ) +description: C# で LINQ を使用して、内部結合を実行する方法について説明します。 +ms.date: 12/1/2016 +ms.assetid: 45bceed6-f549-4114-a9b1-b44feb497742 +ms.openlocfilehash: 5dedab3fe83d4c16f8f0879f564cdd39e2b2446c +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404201" --- # 内部結合の実行 -リレーショナル データベースでは、"*内部結合*" により、2 番目のコレクション内の一致するすべての要素に対して、最初のコレクションの各要素が一度表示される結果セットが生成されます。 最初のコレクション内の要素に一致する要素が存在しない場合、その要素は結果セットには表示されません。 メソッドは、C# の `join` 句によって呼び出され、内部結合を実装します。 - - このトピックでは、次の 4 種類の内部結合を実行する方法を示します。 - -- 簡単なキーに基づいて、2 つのデータ ソースの要素を関連付ける単純な内部結合。 - -- "*複合*" キーに基づいて、2 つのデータ ソースの要素を関連付ける内部結合。 複合キーは複数の値で構成され、複数のプロパティに基づいて要素を関連付けることができます。 - -- 一連の結合操作が相互に追加された "*複数の結合*"。 - -- グループ結合を使用して実装された内部結合。 - -## 例 - -## 簡単なキーの結合の例 - 次の例は、2 つのユーザー定義型オブジェクト、`Person` と `Pet` が含まれた 2 つのコレクションを作成します。 クエリでは、C# の `join` 句を使用して、`Person` オブジェクトを `Owner` がこの `Person` である `Pet` オブジェクトを照合します。 C# の `select` 句では、結果のオブジェクトの表示内容を定義します。 この例では、結果のオブジェクトは、飼い主の姓とペットの名前で構成される匿名型です。 - - [!code-csharp[CsLINQProgJoining#1](../../../samples/snippets/csharp/concepts/linq/how-to-perform-inner-joins_1.cs)] - - `LastName` が "Huff" の `Person` オブジェクトは、`Pet.Owner` がその `Person` に等しい `Pet` オブジェクトがないため、結果セットに表示されません。 - -## 例 - -## 複合キーの結合の例 - 1 つのプロパティだけに基づいて要素を関連付ける代わりに、複合キーを使用して、複数のプロパティに基づいて要素を比較できます。 これを行うには、各コレクションに対してキー セレクター関数を指定し、比較するプロパティで構成された匿名型を返します。 プロパティにラベルを付ける場合は、各キーの匿名型に同じラベルを付ける必要があります。 また、プロパティは、同じ順序で表示する必要があります。 - - 次の例は、`Employee` オブジェクトのリストと `Student` オブジェクトのリストを使用して、学生でもある社員を調べます。 これらの型の両方に、 型の `FirstName` プロパティと `LastName` プロパティがあります。 それぞれのリストの要素から結合キーを作成する関数が、各要素の `FirstName` プロパティと `LastName` プロパティで構成された匿名型を返します。 結合操作により、これらの複合キーが等しいかどうか比較され、それぞれのリストの氏名が一致するオブジェクトのペアが返されます。 - - [!code-csharp[CsLINQProgJoining#2](../../../samples/snippets/csharp/concepts/linq/how-to-perform-inner-joins_2.cs)] - -## 例 - -## 複数の結合の例 - 任意の数の結合操作を相互に追加して、複数の結合を実行できます。 C# の各 `join` 句は、指定されたデータ ソースを前の結合の結果に関連付けます。 - - 次の例は、`Person` オブジェクトのリスト、`Cat` オブジェクトのリスト、`Dog` オブジェクトのリストの 3 つのコレクションを作成します。 - - C# の最初の `join` 句では、`Cat.Owner` と一致する `Person` オブジェクトに基づいて飼い主と猫を一致させます。 この操作で、`Person` オブジェクトと `Cat.Name` が含まれた匿名型のシーケンスが返されます。 - - C# の 2 番目の `join` 句では、`Person` 型の `Owner` プロパティと動物の名前の最初の文字で構成される複合キーに基づいて、最初の結合で返された匿名型を、指定された犬のリストの `Dog` オブジェクトに関連付けます。 この操作で、一致するそれぞれのペアの `Cat.Name` プロパティと `Dog.Name` プロパティが含まれた匿名型のシーケンスが返されます。 これは内部結合であるため、2 番目のデータ ソースに一致するものが存在する、最初のデータ ソースのオブジェクトのみが返されます。 - - [!code-csharp[CsLINQProgJoining#3](../../../samples/snippets/csharp/concepts/linq/how-to-perform-inner-joins_3.cs)] - -## 例 - -## グループ化結合を使用した内部結合の例 - グループ結合を使用して内部結合を実装する方法を次の例に示します。 - - `query1` で、`Person` オブジェクトのリストは、`Pet.Owner` プロパティと一致する `Person` に基づいて、`Pet` オブジェクトのリストにグループ結合されます。 グループ結合によって、それぞれのグループが `Person` オブジェクトおよび一致する `Pet` オブジェクトのシーケンスで構成された、中間グループのコレクションが作成されます。 - - 2 番目の `from` 句をクエリに追加すると、シーケンスのシーケンスが 1 つの長いシーケンスに結合 (または平坦化) されます。 最後のシーケンスの要素の型は、`select` 句で指定されます。 この例では、この型は、一致する各ペアの `Person.FirstName` プロパティと `Pet.Name` プロパティで構成された匿名型です。 - - `query1` の結果は、`into` 句のない `join` 句を使用して内部結合を実行することで得られた結果セットと同じです。 `query2` 変数は、これと同等のクエリを示しています。 - - [!code-csharp[CsLINQProgJoining#4](../../../samples/snippets/csharp/concepts/linq/how-to-perform-inner-joins_4.cs)] - -## 関連項目 - - - [グループ化結合の実行](perform-grouped-joins.md) - [左外部結合の実行](perform-left-outer-joins.md) - [匿名型](../programming-guide/classes-and-structs/anonymous-types.md) - +リレーショナル データベースでは、"*内部結合*" により、2 番目のコレクション内の一致するすべての要素に対して、最初のコレクションの各要素が一度表示される結果セットが生成されます。 最初のコレクション内の要素に一致する要素が存在しない場合、その要素は結果セットには表示されません。 メソッドは、C# の `join` 句によって呼び出され、内部結合を実装します。 + +この記事では、次の 4 種類の内部結合を実行する方法を示します。 + +- 簡単なキーに基づいて、2 つのデータ ソースの要素を関連付ける単純な内部結合。 + +- "*複合*" キーに基づいて、2 つのデータ ソースの要素を関連付ける内部結合。 複合キーは複数の値で構成され、複数のプロパティに基づいて要素を関連付けることができます。 + +- 一連の結合操作が相互に追加された "*複数の結合*"。 + +- グループ結合を使用して実装された内部結合。 + +## 例 - 簡単なキーの結合 + +次の例は、2 つのユーザー定義型オブジェクト、`Person` と `Pet` が含まれた 2 つのコレクションを作成します。 クエリでは、C# の `join` 句を使用して、`Person` オブジェクトを `Owner` がこの `Person` である `Pet` オブジェクトを照合します。 C# の `select` 句では、結果のオブジェクトの表示内容を定義します。 この例では、結果のオブジェクトは、飼い主の姓とペットの名前で構成される匿名型です。 + +[!code-csharp[CsLINQProgJoining#1](~/samples/snippets/csharp/concepts/linq/how-to-perform-inner-joins_1.cs)] + +`LastName` が "Huff" の `Person` オブジェクトは、`Pet.Owner` がその `Person` に等しい `Pet` オブジェクトがないため、結果セットに表示されません。 + +## 例 - 複合キーの結合 + +1 つのプロパティだけに基づいて要素を関連付ける代わりに、複合キーを使用して、複数のプロパティに基づいて要素を比較できます。 これを行うには、各コレクションに対してキー セレクター関数を指定し、比較するプロパティで構成された匿名型を返します。 プロパティにラベルを付ける場合は、各キーの匿名型に同じラベルを付ける必要があります。 また、プロパティは、同じ順序で表示する必要があります。 + +次の例は、`Employee` オブジェクトのリストと `Student` オブジェクトのリストを使用して、学生でもある社員を調べます。 これらの型の両方に、 型の `FirstName` プロパティと `LastName` プロパティがあります。 それぞれのリストの要素から結合キーを作成する関数が、各要素の `FirstName` プロパティと `LastName` プロパティで構成された匿名型を返します。 結合操作により、これらの複合キーが等しいかどうか比較され、それぞれのリストの氏名が一致するオブジェクトのペアが返されます。 + +[!code-csharp[CsLINQProgJoining#2](~/samples/snippets/csharp/concepts/linq/how-to-perform-inner-joins_2.cs)] + +## 例 - 複数の結合 + +任意の数の結合操作を相互に追加して、複数の結合を実行できます。 C# の各 `join` 句は、指定されたデータ ソースを前の結合の結果に関連付けます。 + +次の例は、`Person` オブジェクトのリスト、`Cat` オブジェクトのリスト、`Dog` オブジェクトのリストの 3 つのコレクションを作成します。 + +C# の最初の `join` 句では、`Cat.Owner` と一致する `Person` オブジェクトに基づいて飼い主と猫を一致させます。 この操作で、`Person` オブジェクトと `Cat.Name` が含まれた匿名型のシーケンスが返されます。 + +C# の 2 番目の `join` 句では、`Person` 型の `Owner` プロパティと動物の名前の最初の文字で構成される複合キーに基づいて、最初の結合で返された匿名型を、指定された犬のリストの `Dog` オブジェクトに関連付けます。 この操作で、一致するそれぞれのペアの `Cat.Name` プロパティと `Dog.Name` プロパティが含まれた匿名型のシーケンスが返されます。 これは内部結合であるため、2 番目のデータ ソースに一致するものが存在する、最初のデータ ソースのオブジェクトのみが返されます。 + +[!code-csharp[CsLINQProgJoining#3](~/samples/snippets/csharp/concepts/linq/how-to-perform-inner-joins_3.cs)] + +## 例 - グループ化結合を使用した内部結合 + +グループ結合を使用して内部結合を実装する方法を次の例に示します。 + +`query1` で、`Person` オブジェクトのリストは、`Pet.Owner` プロパティと一致する `Person` に基づいて、`Pet` オブジェクトのリストにグループ結合されます。 グループ結合によって、それぞれのグループが `Person` オブジェクトおよび一致する `Pet` オブジェクトのシーケンスで構成された、中間グループのコレクションが作成されます。 + +2 番目の `from` 句をクエリに追加すると、シーケンスのシーケンスが 1 つの長いシーケンスに結合 (または平坦化) されます。 最後のシーケンスの要素の型は、`select` 句で指定されます。 この例では、この型は、一致する各ペアの `Person.FirstName` プロパティと `Pet.Name` プロパティで構成された匿名型です。 + +`query1` の結果は、`into` 句のない `join` 句を使用して内部結合を実行することで得られた結果セットと同じです。 `query2` 変数は、これと同等のクエリを示しています。 + +[!code-csharp[CsLINQProgJoining#4](~/samples/snippets/csharp/concepts/linq/how-to-perform-inner-joins_4.cs)] + +## 関連項目 + + + +[グループ化結合の実行](perform-grouped-joins.md) +[左外部結合の実行](perform-left-outer-joins.md) +[匿名型](../programming-guide/classes-and-structs/anonymous-types.md) \ No newline at end of file diff --git a/docs/csharp/linq/perform-left-outer-joins.md b/docs/csharp/linq/perform-left-outer-joins.md index 998d3128997..76539842835 100644 --- a/docs/csharp/linq/perform-left-outer-joins.md +++ b/docs/csharp/linq/perform-left-outer-joins.md @@ -1,34 +1,36 @@ --- -title: 左外部結合の実行 -description: '方法: 左外部結合を実行する。' -ms.date: 12/1/2016 -ms.assetid: f542cee6-3169-4dcf-a631-3a6a79ccd473 -ms.openlocfilehash: aacab1ac6f4ab2c10b393cf0b2c578a13d9b9306 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33284278" +title: 左外部結合の実行 (C# での LINQ) +description: C# で LINQ を使用して、左外部結合を実行する方法について説明します。 +ms.date: 12/1/2016 +ms.assetid: f542cee6-3169-4dcf-a631-3a6a79ccd473 +ms.openlocfilehash: 3da144e6e3293d3a4084f7a99f77aec199f7a267 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37403854" --- # 左外部結合の実行 -左外部結合は、最初のコレクションの各要素を、2 つ目のコレクション内にある要素との相関関係の有無にかかわらず返す結合です。 LINQ を使用すると、グループ結合の結果に対して メソッドを呼び出すことで、左外部結合を実行できます。 - -## 例 - 次の例は、グループ結合の結果に対して メソッドを使用し、左外部結合を実行する方法を示しています。 - - 2 つのコレクションの左外部結合を作成するための最初のステップは、グループ結合を使用して内部結合を実行することです。 (このプロセスの詳細については、「[内部結合の実行](perform-inner-joins.md)」参照してください。)この例では、`Pet.Owner` に一致する `Person` オブジェクトに基づいて、`Person` オブジェクトの一覧が `Pet` オブジェクトの一覧に内部結合されています。 - - 2 つ目のステップは、最初 (左側) のコレクションの各要素を結果セットに含めることです。このとき、その要素と一致するものが右のコレクションにあるかどうかは考慮しません。 これを行うには、グループ結合内の一致する要素の各シーケンスに対して、 を呼び出します。 この例では、`Pet` オブジェクトに一致する各シーケンスに対して、 が呼び出されています。 このメソッドは、`Person` オブジェクトに対して一致する `Pet` オブジェクトのシーケンスが空である場合に、単一の既定値を含んだコレクションを返します。これにより、各 `Person` オブジェクトが結果コレクション内に表されることが保証されます。 - + +左外部結合は、最初のコレクションの各要素を、2 つ目のコレクション内にある要素との相関関係の有無にかかわらず返す結合です。 LINQ を使用すると、グループ結合の結果に対して メソッドを呼び出すことで、左外部結合を実行できます。 + +## 例 + +次の例は、グループ結合の結果に対して メソッドを使用し、左外部結合を実行する方法を示しています。 + +2 つのコレクションの左外部結合を作成するための最初のステップは、グループ結合を使用して内部結合を実行することです。 (このプロセスの詳細については、「[内部結合の実行](perform-inner-joins.md)」参照してください。)この例では、`Pet.Owner` に一致する `Person` オブジェクトに基づいて、`Person` オブジェクトの一覧が `Pet` オブジェクトの一覧に内部結合されています。 + +2 つ目のステップは、最初 (左側) のコレクションの各要素を結果セットに含めることです。このとき、その要素と一致するものが右のコレクションにあるかどうかは考慮しません。 これを行うには、グループ結合内の一致する要素の各シーケンスに対して、 を呼び出します。 この例では、`Pet` オブジェクトに一致する各シーケンスに対して、 が呼び出されています。 このメソッドは、`Person` オブジェクトに対して一致する `Pet` オブジェクトのシーケンスが空である場合に、単一の既定値を含んだコレクションを返します。これにより、各 `Person` オブジェクトが結果コレクション内に表されることが保証されます。 + > [!NOTE] -> 参照型の既定値は `null` です。そのためこのコード例では、各 `Pet` コレクションの各要素にアクセスする前に Null 参照がチェックされます。 - - [!code-csharp[CsLINQProgJoining#7](../../../samples/snippets/csharp/concepts/linq/how-to-perform-left-outer-joins_1.cs)] - -## 関連項目 - - - [内部結合の実行](perform-inner-joins.md) - [グループ化結合の実行](perform-grouped-joins.md) - [匿名型](../programming-guide/classes-and-structs/anonymous-types.md) - +> 参照型の既定値は `null` です。そのためこのコード例では、各 `Pet` コレクションの各要素にアクセスする前に Null 参照がチェックされます。 + +[!code-csharp[CsLINQProgJoining#7](~/samples/snippets/csharp/concepts/linq/how-to-perform-left-outer-joins_1.cs)] + +## 関連項目 + + + +[内部結合の実行](perform-inner-joins.md) +[グループ化結合の実行](perform-grouped-joins.md) +[匿名型](../programming-guide/classes-and-structs/anonymous-types.md) \ No newline at end of file diff --git a/docs/csharp/linq/query-a-collection-of-objects.md b/docs/csharp/linq/query-a-collection-of-objects.md index 87792e10e8a..19ea4583b7b 100644 --- a/docs/csharp/linq/query-a-collection-of-objects.md +++ b/docs/csharp/linq/query-a-collection-of-objects.md @@ -1,28 +1,30 @@ --- -title: オブジェクトのコレクションの照会 -description: コレクションをクエリする方法。 -ms.date: 11/30/2016 -ms.assetid: 87a76f8a-0b58-4791-90ea-2fe0a30416c9 -ms.openlocfilehash: c690da2ae59d2a9b34a5bd403bc54797c4e95fa0 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33282393" +title: オブジェクトのコレクションの照会 (C# での LINQ) +description: C# で LINQ を使用して、コレクションを照会する方法について説明します。 +ms.date: 11/30/2016 +ms.assetid: 87a76f8a-0b58-4791-90ea-2fe0a30416c9 +ms.openlocfilehash: 87c7bbe789c165a6e189231df1979fc264a34dce +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37403922" --- # オブジェクトのコレクションの照会 + この例では、`Student` オブジェクトのリストに対してシンプルなクエリを実行する方法を示します。 各 `Student` オブジェクトには、生徒に関する基本情報と、4 回の試験での生徒の点数を表すリストが含まれています。 - このアプリケーションは、同じ `students` データ ソースを使用する、このセクション内のその他多くの例のフレームワークとして機能します。 +このアプリケーションは、同じ `students` データ ソースを使用する、このセクション内のその他多くの例のフレームワークとして機能します。 -## 例 - 次のクエリは、最初の試験で 90 点以上を取った学生を返します。 +## 例 + +次のクエリは、最初の試験で 90 点以上を取った学生を返します。 - [!code-csharp[csProgGuideLINQ#15](../../../samples/snippets/csharp/concepts/linq/how-to-query-a-collection-of-objects_1.cs)] +[!code-csharp[csProgGuideLINQ#15](~/samples/snippets/csharp/concepts/linq/how-to-query-a-collection-of-objects_1.cs)] - このクエリは、実験用として意図的にシンプルに記述されています。 たとえば、`where` 句でより多く条件を試したり、`orderby` 句を使用して結果を並べ替えたりすることもできます。 +このクエリは、実験用として意図的にシンプルに記述されています。 たとえば、`where` 句でより多く条件を試したり、`orderby` 句を使用して結果を並べ替えたりすることもできます。 +## 関連項目 -## 関連項目 - [LINQ クエリ式](index.md) - [文字列補間](../language-reference/tokens/interpolated.md) +[統合言語クエリ (LINQ)](index.md) +[文字列補間](../language-reference/tokens/interpolated.md) \ No newline at end of file diff --git a/docs/csharp/linq/query-expression-basics.md b/docs/csharp/linq/query-expression-basics.md index 289c5c1a236..be5c87d5f5c 100644 --- a/docs/csharp/linq/query-expression-basics.md +++ b/docs/csharp/linq/query-expression-basics.md @@ -1,176 +1,180 @@ --- -title: クエリ式の基本 -description: クエリ式に関連する概念について説明します -ms.date: 11/30/2016 -ms.assetid: 027db1f8-346f-44d2-a16e-043fcea3a4e0 -ms.openlocfilehash: d211b0770bdc69f513e4129c818f96650de63e77 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33288994" +title: クエリ式の基本 (C# での LINQ) +description: クエリ式に関連する概念について説明します +ms.date: 11/30/2016 +ms.assetid: 027db1f8-346f-44d2-a16e-043fcea3a4e0 +ms.openlocfilehash: 9533fcb76e0c06e7fd20cb4c7ffc6e4980cfc30f +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404542" --- # クエリ式の基本 -## クエリとは何か。またどのような働きをするのか - - *クエリ*とは、指定したデータ ソース (単一または複数) からどのようなデータを取得し、それらのデータをどのような形式と編成で返すかを説明した、命令のセットです。 クエリは、それが生成する結果とは区別されます。 - - 一般に、ソース データは、同じ種類の要素のシーケンスとして論理的に編成されます。 たとえば、SQL データベース テーブルには、行のシーケンスが含まれています。 XML ファイルには、XML 要素のシーケンスがあります (ただし、これらはツリー構造で階層化されています)。 メモリ内コレクションには、オブジェクトのシーケンスが含まれています。 - - アプリケーションの観点から言うと、元のソース データの特定の型や構造体はは重要ではありません。 アプリケーションは常に、ソース データを または コレクションとして認識します。 たとえば、LINQ to XML では、ソース データは `IEnumerable`\<> として表示されます。 - - クエリは、このソース シーケンスに対して、次の 3 つのうち、いずれかの操作を行います。 - -- 個々 の要素を変更することなく、要素のサブセットを取得して新しいシーケンスを生成する。 クエリはその後、次の例のように、返されたシーケンスをさまざまな方法で並べ替えたり、グループ化する場合があります (例では `scores` を `int[]` と想定)。 - - [!code-csharp[csrefQueryExpBasics#45](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_1.cs)] - -- 上記の例のように要素のシーケンスを取得するが、それらを新しい型のオブジェクトに変換する。 たとえば、クエリでは、データ ソース内の特定の顧客レコードから姓だけを取得することがあります。 また、完全なレコードを取得し、それを使用して別のメモリ内オブジェクト型や XML データを構築した後、最終的な結果シーケンスを生成することもあります。 次の例では、`int` から `string` へのプロジェクションを行っています。 `highScoresQuery` の新しい型があることに注目してください。 - - [!code-csharp[csrefQueryExpBasics#46](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_2.cs)] - -- ソース データに関するシングルトン値を取得します。次に例を示します。 - - - 特定の条件に一致する要素の数。 - - - 最大値または最小値を持つ要素。 - - - 条件に一致する最初の要素や、指定された要素セット内の特定の値の合計。 たとえば、次のクエリは、整数配列 `scores` から、80 より大きいスコアの数を返します。 - - [!code-csharp[csrefQueryExpBasics#47](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_3.cs)] - - 上記の例では、`Count` メソッドに対する呼び出しの前に、クエリ式を囲むかっこが使用されています。 これは、具体的な結果を格納する新しい変数を使用しても表現できます。 この手法では、クエリを格納する変数が、結果を格納するクエリとは別に保持されるので、コードがより読みやすくなります。 - - [!code-csharp[csrefQueryExpBasics#48](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_4.cs)] - - 上記の例では、`Count` に対する呼び出しの前でクエリが実行されています。これは、`highScoresQuery` によって返された要素の数を確認するために、`Count` が結果を反復処理する必要があるためです。 - -## クエリ式とは何か - - *クエリ式*とは、クエリ構文で表されたクエリのことです。 クエリ式は、ファーストクラスの言語コンストラクトです。 他の式とよく似ていて、C# 式が有効である任意のコンテキストで使用できます。 クエリ式の構文は、SQL や XQuery などのような宣言型の構文で記述された、一連の句で構成されます。 各句には 1 つ以上の C# 式が含まれていて、それらの式は、それ自体がクエリ式である場合もあれば、クエリ式を含んでいる場合もあります。 - - クエリ式は [from](../language-reference/keywords/from-clause.md) 句で始まり、[select](../language-reference/keywords/select-clause.md) または [group](../language-reference/keywords/group-clause.md) 句で終わる必要があります。 最初の `from` 句と最後の `select` または `group` 句の間には、次の省略可能句を 1 つ以上含めることができます: [where](../language-reference/keywords/where-clause.md)、[orderby](../language-reference/keywords/orderby-clause.md)、[join](../language-reference/keywords/join-clause.md)、[let](../language-reference/keywords/let-clause.md)、および追加の [from](../language-reference/keywords/from-clause.md) 句。 また、[into](../language-reference/keywords/into.md) キーワードを使用して、`join` 句や `group` 句の結果を、同じクエリ式内の追加のクエリ句のソースとして使用することもできます。 - -### クエリ変数 - - LINQ では、クエリの*結果*ではなく、*クエリ*を格納する変数を、クエリ変数と呼びます。 より具体的に言うと、クエリ変数は常に列挙可能な型であり、`foreach` ステートメントか、または `IEnumerator.MoveNext` メソッドに対する直接呼び出しで反復処理された場合に、要素のシーケンスを生成します。 - - 次のコード例は、データ ソース、フィルター句、および並べ替え句がそれぞれ 1 つずつあり、ソース要素の変換がない、簡単なクエリ式を示したものです。 `select` 句でクエリが終わっています。 - - [!code-csharp[csrefQueryExpBasics#49](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_5.cs)] - - 上記の例では、`scoreQuery` が *クエリ変数*です。クエリ変数は単に*クエリ*と呼ばれることもあります。 クエリ変数には、`foreach` ループで生成された実際の結果データは格納されません。 また、`foreach` ステートメントが実行されたとき、クエリ結果はクエリ変数 `scoreQuery` を通じては返されません。 結果は反復変数 `testScore` を通じて返されます。 `scoreQuery` 変数は 2 番目の `foreach` ループで反復処理できます。 この変数とデータ ソースのどちらかが変更されないかぎり、同じ結果が生成されます。 - - クエリ変数には、クエリ構文、メソッド構文、またはそれら 2 つの組合せで表現されたクエリが格納される場合があります。 次の例では、`queryMajorCities` と `queryMajorCities2` の両方がクエリ変数です。 - - [!code-csharp[csrefQueryExpBasics#50](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_6.cs)] - - これに対し、次の 2 つの例は、クエリで初期化されてはいるものの、クエリ変数ではない変数を示しています。 これらは結果を格納するので、クエリ変数ではありません。 - - [!code-csharp[csrefQueryExpBasics#51](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_7.cs)] - - クエリのさまざまな表現方法については、「[LINQ でのクエリ構文とメソッド構文](../programming-guide/concepts/linq/query-syntax-and-method-syntax-in-linq.md)」をご覧ください。 - -#### クエリ変数の明示的型指定と暗黙的型指定 - - このドキュメントでは通常、明示的な型のクエリ変数で説明を行います。これは、クエリ変数と [select 句](../language-reference/keywords/select-clause.md)の関係を示すためです。 ただし、 [var](../language-reference/keywords/var.md) キーワードを使用すれば、コンパイル時にクエリ変数 (またはその他のローカル変数) の型を推論するようにコンパイラに指示することもできます。 たとえば、このトピックで先に示したクエリの例は、暗黙的な型指定を使用しても表現できます。 - - [!code-csharp[csrefQueryExpBasics#52](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_8.cs)] - - 詳しくは、「[暗黙的に型指定されるローカル変数](../programming-guide/classes-and-structs/implicitly-typed-local-variables.md)」および「[LINQ クエリ操作での型の関係](../programming-guide/concepts/linq/type-relationships-in-linq-query-operations.md)」をご覧ください。 - -### クエリ式の開始 - - クエリ式は、`from` 句で始める必要があります。 この句では、データ ソースと範囲変数を指定します。 範囲変数は、ソース シーケンスが走査されるときの、ソース シーケンス内の連続する各要素を表します。 範囲変数は、データ ソース内の要素の型に基づいて厳密に型指定されます。 次の例では、`countries` が `Country` オブジェクトの配列であるため、範囲変数も `Country` として型指定されています。 範囲変数は厳密に型指定されるので、ドット演算子を使用して、その型の利用可能なメンバーにアクセスすることができます。 - - [!code-csharp[csrefQueryExpBasics#53](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_9.cs)] - - 範囲変数は、クエリがセミコロンまたは *continuation* 句で終了するまでスコープ内に維持されます。 - - クエリ式には、複数の `from` 句を含めることができます。 ソース シーケンス内の各要素がそれ自体コレクションであるか、またはコレクションを格納している場合には、追加の `from` 句を使用します。 たとえば、`Country` オブジェクトのコレクションがあり、各オブジェクトに、`Cities` という名前の `City` オブジェクトのコレクションが格納されているとします。 その場合、各 `Country` 内の `City` オブジェクトを照会するには、次のように 2 つの `from` 句を使用します。 - - [!code-csharp[csrefQueryExpBasics#54](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_10.cs)] - - 詳しくは、「[from 句](../language-reference/keywords/from-clause.md)」をご覧ください。 - -### クエリ式の終了 - - クエリ式は、`group` 句または `select` 句のいずれかで終わる必要があります。 - -#### group 句 - - `group` 句は、指定したキーによって編成されたグループのシーケンスを生成するために使用します。 キーには、任意のデータ型を指定できます。 たとえば、次のクエリでは、1 つ以上の `Country` オブジェクトを含み、キーが `char` 値であるグループのシーケンスが作成されます。 - - [!code-csharp[csrefQueryExpBasics#55](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_11.cs)] - - グループ化について詳しくは、「[group 句](../language-reference/keywords/group-clause.md)」をご覧ください。 - -#### select 句 - `select` 句は、その他すべての型のシーケンスを生成するために使用します。 シンプルな `select` 句は、データ ソース内に含まれるオブジェクトと同じ型のオブジェクトのシーケンスを生成します。 この例では、データ ソースに `Country` オブジェクトが含まれています。 `orderby` 句は要素を新しい順序に並べ替え、`select` 句は並べ替えられた `Country` オブジェクトのシーケンスを生成します。 - - [!code-csharp[csrefQueryExpBasics#56](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_12.cs)] - - `select` 句は、ソース データを新しい型のシーケンスに変換するために使用できます。 この変換は、*プロジェクション*とも呼ばれます。 次の例では、`select` 句は元の要素内にあるフィールドのサブセットのみを含んだ、匿名型のシーケンスを*プロジェクト*します。 新しいオブジェクトはオブジェクト初期化子を使用して初期化されています。 - - [!code-csharp[csrefQueryExpBasics#57](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_13.cs)] - - `select` 句を使用してソース データを変換する方法について詳しくは、「[select 句](../language-reference/keywords/select-clause.md)」をご覧ください。 - -#### "into" を使用した継続 - - `select` 句または `group` 句で `into` キーワードを使用すると、クエリを格納する一時的な識別子を作成できます。 これは、grouping 操作や select 操作の後、クエリに対する追加のクエリ操作を実行する必要がある場合に便利です。 次の例では、1 千万という範囲の人口で `countries` をグループ化しています。 これらのグループが作成された後、追加の句で一部のグループを除外し、その後、グループを昇順で並べ替えようとしています。 これらの追加操作を実行するには、`countryGroup` によって継続を表す必要があります。 - - [!code-csharp[csrefQueryExpBasics#58](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_14.cs)] - - 詳しくは、「[into](../language-reference/keywords/into.md)」をご覧ください。 - +この記事では、C# でのクエリ式に関連する基本概念について説明します。 + +## クエリとは何か。またどのような働きをするのか + +*クエリ*とは、指定したデータ ソース (単一または複数) からどのようなデータを取得し、それらのデータをどのような形式と編成で返すかを説明した、命令のセットです。 クエリは、それが生成する結果とは区別されます。 + +一般に、ソース データは、同じ種類の要素のシーケンスとして論理的に編成されます。 たとえば、SQL データベース テーブルには、行のシーケンスが含まれています。 XML ファイルには、XML 要素のシーケンスがあります (ただし、これらはツリー構造で階層化されています)。 メモリ内コレクションには、オブジェクトのシーケンスが含まれています。 + +アプリケーションの観点から言うと、元のソース データの特定の型や構造体はは重要ではありません。 アプリケーションは常に、ソース データを または コレクションとして認識します。 たとえば、LINQ to XML では、ソース データは `IEnumerable`\<> として表示されます。 + +クエリは、このソース シーケンスに対して、次の 3 つのうち、いずれかの操作を行います。 + +- 個々 の要素を変更することなく、要素のサブセットを取得して新しいシーケンスを生成する。 クエリはその後、次の例のように、返されたシーケンスをさまざまな方法で並べ替えたり、グループ化する場合があります (例では `scores` を `int[]` と想定)。 + + [!code-csharp[csrefQueryExpBasics#45](~/samples/snippets/csharp/concepts/linq/query-expression-basics_1.cs)] + +- 上記の例のように要素のシーケンスを取得するが、それらを新しい型のオブジェクトに変換する。 たとえば、クエリでは、データ ソース内の特定の顧客レコードから姓だけを取得することがあります。 また、完全なレコードを取得し、それを使用して別のメモリ内オブジェクト型や XML データを構築した後、最終的な結果シーケンスを生成することもあります。 次の例では、`int` から `string` へのプロジェクションを行っています。 `highScoresQuery` の新しい型があることに注目してください。 + + [!code-csharp[csrefQueryExpBasics#46](~/samples/snippets/csharp/concepts/linq/query-expression-basics_2.cs)] + +- ソース データに関するシングルトン値を取得します。次に例を示します。 + + - 特定の条件に一致する要素の数。 + + - 最大値または最小値を持つ要素。 + + - 条件に一致する最初の要素や、指定された要素セット内の特定の値の合計。 たとえば、次のクエリは、整数配列 `scores` から、80 より大きいスコアの数を返します。 + + [!code-csharp[csrefQueryExpBasics#47](~/samples/snippets/csharp/concepts/linq/query-expression-basics_3.cs)] + + 上記の例では、`Count` メソッドに対する呼び出しの前に、クエリ式を囲むかっこが使用されています。 これは、具体的な結果を格納する新しい変数を使用しても表現できます。 この手法では、クエリを格納する変数が、結果を格納するクエリとは別に保持されるので、コードがより読みやすくなります。 + + [!code-csharp[csrefQueryExpBasics#48](~/samples/snippets/csharp/concepts/linq/query-expression-basics_4.cs)] + +上記の例では、`Count` に対する呼び出しの前でクエリが実行されています。これは、`highScoresQuery` によって返された要素の数を確認するために、`Count` が結果を反復処理する必要があるためです。 + +## クエリ式とは何か + +*クエリ式*とは、クエリ構文で表されたクエリのことです。 クエリ式は、ファーストクラスの言語コンストラクトです。 他の式とよく似ていて、C# 式が有効である任意のコンテキストで使用できます。 クエリ式の構文は、SQL や XQuery などのような宣言型の構文で記述された、一連の句で構成されます。 各句には 1 つ以上の C# 式が含まれていて、それらの式は、それ自体がクエリ式である場合もあれば、クエリ式を含んでいる場合もあります。 + +クエリ式は [from](../language-reference/keywords/from-clause.md) 句で始まり、[select](../language-reference/keywords/select-clause.md) または [group](../language-reference/keywords/group-clause.md) 句で終わる必要があります。 最初の `from` 句と最後の `select` または `group` 句の間には、次の省略可能句を 1 つ以上含めることができます: [where](../language-reference/keywords/where-clause.md)、[orderby](../language-reference/keywords/orderby-clause.md)、[join](../language-reference/keywords/join-clause.md)、[let](../language-reference/keywords/let-clause.md)、および追加の [from](../language-reference/keywords/from-clause.md) 句。 また、[into](../language-reference/keywords/into.md) キーワードを使用して、`join` 句や `group` 句の結果を、同じクエリ式内の追加のクエリ句のソースとして使用することもできます。 + +### クエリ変数 + +LINQ では、クエリの*結果*ではなく、*クエリ*を格納する変数を、クエリ変数と呼びます。 より具体的に言うと、クエリ変数は常に列挙可能な型であり、`foreach` ステートメントか、または `IEnumerator.MoveNext` メソッドに対する直接呼び出しで反復処理された場合に、要素のシーケンスを生成します。 + +次のコード例は、データ ソース、フィルター句、および並べ替え句がそれぞれ 1 つずつあり、ソース要素の変換がない、簡単なクエリ式を示したものです。 `select` 句でクエリが終わっています。 + +[!code-csharp[csrefQueryExpBasics#49](~/samples/snippets/csharp/concepts/linq/query-expression-basics_5.cs)] + +上記の例では、`scoreQuery` が *クエリ変数*です。クエリ変数は単に*クエリ*と呼ばれることもあります。 クエリ変数には、`foreach` ループで生成された実際の結果データは格納されません。 また、`foreach` ステートメントが実行されたとき、クエリ結果はクエリ変数 `scoreQuery` を通じては返されません。 結果は反復変数 `testScore` を通じて返されます。 `scoreQuery` 変数は 2 番目の `foreach` ループで反復処理できます。 この変数とデータ ソースのどちらかが変更されないかぎり、同じ結果が生成されます。 + +クエリ変数には、クエリ構文、メソッド構文、またはそれら 2 つの組合せで表現されたクエリが格納される場合があります。 次の例では、`queryMajorCities` と `queryMajorCities2` の両方がクエリ変数です。 + +[!code-csharp[csrefQueryExpBasics#50](~/samples/snippets/csharp/concepts/linq/query-expression-basics_6.cs)] + +これに対し、次の 2 つの例は、クエリで初期化されてはいるものの、クエリ変数ではない変数を示しています。 これらは結果を格納するので、クエリ変数ではありません。 + +[!code-csharp[csrefQueryExpBasics#51](~/samples/snippets/csharp/concepts/linq/query-expression-basics_7.cs)] + +クエリのさまざまな表現方法については、「[LINQ でのクエリ構文とメソッド構文](../programming-guide/concepts/linq/query-syntax-and-method-syntax-in-linq.md)」をご覧ください。 + +#### クエリ変数の明示的型指定と暗黙的型指定 + +このドキュメントでは通常、明示的な型のクエリ変数で説明を行います。これは、クエリ変数と [select 句](../language-reference/keywords/select-clause.md)の関係を示すためです。 ただし、 [var](../language-reference/keywords/var.md) キーワードを使用すれば、コンパイル時にクエリ変数 (またはその他のローカル変数) の型を推論するようにコンパイラに指示することもできます。 たとえば、このトピックで先に示したクエリの例は、暗黙的な型指定を使用しても表現できます。 + +[!code-csharp[csrefQueryExpBasics#52](~/samples/snippets/csharp/concepts/linq/query-expression-basics_8.cs)] + +詳しくは、「[暗黙的に型指定されるローカル変数](../programming-guide/classes-and-structs/implicitly-typed-local-variables.md)」および「[LINQ クエリ操作での型の関係](../programming-guide/concepts/linq/type-relationships-in-linq-query-operations.md)」をご覧ください。 + +### クエリ式の開始 + +クエリ式は、`from` 句で始める必要があります。 この句では、データ ソースと範囲変数を指定します。 範囲変数は、ソース シーケンスが走査されるときの、ソース シーケンス内の連続する各要素を表します。 範囲変数は、データ ソース内の要素の型に基づいて厳密に型指定されます。 次の例では、`countries` が `Country` オブジェクトの配列であるため、範囲変数も `Country` として型指定されています。 範囲変数は厳密に型指定されるので、ドット演算子を使用して、その型の利用可能なメンバーにアクセスすることができます。 + +[!code-csharp[csrefQueryExpBasics#53](~/samples/snippets/csharp/concepts/linq/query-expression-basics_9.cs)] + +範囲変数は、クエリがセミコロンまたは *continuation* 句で終了するまでスコープ内に維持されます。 + +クエリ式には、複数の `from` 句を含めることができます。 ソース シーケンス内の各要素がそれ自体コレクションであるか、またはコレクションを格納している場合には、追加の `from` 句を使用します。 たとえば、`Country` オブジェクトのコレクションがあり、各オブジェクトに、`Cities` という名前の `City` オブジェクトのコレクションが格納されているとします。 その場合、各 `Country` 内の `City` オブジェクトを照会するには、次のように 2 つの `from` 句を使用します。 + +[!code-csharp[csrefQueryExpBasics#54](~/samples/snippets/csharp/concepts/linq/query-expression-basics_10.cs)] + +詳しくは、「[from 句](../language-reference/keywords/from-clause.md)」をご覧ください。 + +### クエリ式の終了 + +クエリ式は、`group` 句または `select` 句のいずれかで終わる必要があります。 + +#### group 句 + +`group` 句は、指定したキーによって編成されたグループのシーケンスを生成するために使用します。 キーには、任意のデータ型を指定できます。 たとえば、次のクエリでは、1 つ以上の `Country` オブジェクトを含み、キーが `char` 値であるグループのシーケンスが作成されます。 + +[!code-csharp[csrefQueryExpBasics#55](~/samples/snippets/csharp/concepts/linq/query-expression-basics_11.cs)] + +グループ化について詳しくは、「[group 句](../language-reference/keywords/group-clause.md)」をご覧ください。 + +#### select 句 + +`select` 句は、その他すべての型のシーケンスを生成するために使用します。 シンプルな `select` 句は、データ ソース内に含まれるオブジェクトと同じ型のオブジェクトのシーケンスを生成します。 この例では、データ ソースに `Country` オブジェクトが含まれています。 `orderby` 句は要素を新しい順序に並べ替え、`select` 句は並べ替えられた `Country` オブジェクトのシーケンスを生成します。 + +[!code-csharp[csrefQueryExpBasics#56](~/samples/snippets/csharp/concepts/linq/query-expression-basics_12.cs)] + +`select` 句は、ソース データを新しい型のシーケンスに変換するために使用できます。 この変換は、*プロジェクション*とも呼ばれます。 次の例では、`select` 句は元の要素内にあるフィールドのサブセットのみを含んだ、匿名型のシーケンスを*プロジェクト*します。 新しいオブジェクトはオブジェクト初期化子を使用して初期化されています。 + +[!code-csharp[csrefQueryExpBasics#57](~/samples/snippets/csharp/concepts/linq/query-expression-basics_13.cs)] + +`select` 句を使用してソース データを変換する方法について詳しくは、「[select 句](../language-reference/keywords/select-clause.md)」をご覧ください。 + +#### "into" を使用した継続 + +`select` 句または `group` 句で `into` キーワードを使用すると、クエリを格納する一時的な識別子を作成できます。 これは、grouping 操作や select 操作の後、クエリに対する追加のクエリ操作を実行する必要がある場合に便利です。 次の例では、1 千万という範囲の人口で `countries` をグループ化しています。 これらのグループが作成された後、追加の句で一部のグループを除外し、その後、グループを昇順で並べ替えようとしています。 これらの追加操作を実行するには、`countryGroup` によって継続を表す必要があります。 + +[!code-csharp[csrefQueryExpBasics#58](~/samples/snippets/csharp/concepts/linq/query-expression-basics_14.cs)] + +詳しくは、「[into](../language-reference/keywords/into.md)」をご覧ください。 + ### フィルター処理、並べ替え、および結合 - 開始の `from` 句と、終了の `select` または`group`句の間には、その他のすべての省略可能句 (`where`、`join`、`orderby`、`from`、`let`) を必要に応じて使用できます。 省略可能句は、クエリ本文で任意の回数 (0 回~複数回) 使用できます。 - -#### where 句 +開始の `from` 句と、終了の `select` または`group`句の間には、その他のすべての省略可能句 (`where`、`join`、`orderby`、`from`、`let`) を必要に応じて使用できます。 省略可能句は、クエリ本文で任意の回数 (0 回~複数回) 使用できます。 + +#### where 句 + +`where` 句は、1 つ以上の述語式に基づいて、ソース データから要素を除外するために使用します。 次の例では、`where` 句に 1 つの述語と 2 つの条件があります。 + +[!code-csharp[csrefQueryExpBasics#59](~/samples/snippets/csharp/concepts/linq/query-expression-basics_15.cs)] + +詳しくは、「[where 句](../language-reference/keywords/where-clause.md)」をご覧ください。 - `where` 句は、1 つ以上の述語式に基づいて、ソース データから要素を除外するために使用します。 次の例では、`where` 句に 1 つの述語と 2 つの条件があります。 - - [!code-csharp[csrefQueryExpBasics#59](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_15.cs)] - - 詳しくは、「[where 句](../language-reference/keywords/where-clause.md)」をご覧ください。 - #### orderby 句 - `orderby` 句は、結果を昇順または降順で並べ替えるために使用します。 第 2 の並べ替え順序を指定することもできます。 次の例では、`Area` プロパティを使用して、`country` オブジェクトに対する 第 1 の並べ替えを実行しています。 その後、`Population` プロパティを使用して第 2 の並べ替えを実行しています。 - - [!code-csharp[csrefQueryExpBasics#60](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_16.cs)] - - `ascending` キーワードは省略可能です。順序が指定されていない場合は、これが既定の並べ替え順序になります。 詳しくは、「[orderby 句](../language-reference/keywords/orderby-clause.md)」をご覧ください。 - +`orderby` 句は、結果を昇順または降順で並べ替えるために使用します。 第 2 の並べ替え順序を指定することもできます。 次の例では、`Area` プロパティを使用して、`country` オブジェクトに対する 第 1 の並べ替えを実行しています。 その後、`Population` プロパティを使用して第 2 の並べ替えを実行しています。 + +[!code-csharp[csrefQueryExpBasics#60](~/samples/snippets/csharp/concepts/linq/query-expression-basics_16.cs)] + +`ascending` キーワードは省略可能です。順序が指定されていない場合は、これが既定の並べ替え順序になります。 詳しくは、「[orderby 句](../language-reference/keywords/orderby-clause.md)」をご覧ください。 + #### join 句 - `join` 句は、各要素内の指定したキー間での等値比較に基づいて、1 つのデータ ソースの要素を別のデータ ソースの要素と関連付けたり、組み合わせたりするために使用します。 LINQ では、join 操作は要素の型が異なるオブジェクトのシーケンスに対して実行されます。 2 つのシーケンスを結合した後には、`select` または `group` ステートメント使用して、出力シーケンスに格納する要素を指定する必要があります。 また、匿名型を使用して、関連付けられた各要素セットのプロパティを、出力シーケンス用の新しい型に結合することもできます。 次の例では、`Category` プロパティが `categories` 文字列配列内のいずれかのカテゴリと一致する `prod` オブジェクトを関連付けています。 `Category` が `categories` 内の文字列に一致しない製品は除外されます。`select` ステートメントは、`cat` と `prod` の両方からプロパティを取った新しい型をプロジェクトしています。 - - [!code-csharp[csrefQueryExpBasics#61](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_17.cs)] - - [into](../language-reference/keywords/into.md) キーワードを使用して `join` 操作の結果を一時変数に格納することにより、グループ結合を実行することもできます。 詳しくは、「[join 句](../language-reference/keywords/join-clause.md)」をご覧ください。 - +`join` 句は、各要素内の指定したキー間での等値比較に基づいて、1 つのデータ ソースの要素を別のデータ ソースの要素と関連付けたり、組み合わせたりするために使用します。 LINQ では、join 操作は要素の型が異なるオブジェクトのシーケンスに対して実行されます。 2 つのシーケンスを結合した後には、`select` または `group` ステートメント使用して、出力シーケンスに格納する要素を指定する必要があります。 また、匿名型を使用して、関連付けられた各要素セットのプロパティを、出力シーケンス用の新しい型に結合することもできます。 次の例では、`Category` プロパティが `categories` 文字列配列内のいずれかのカテゴリと一致する `prod` オブジェクトを関連付けています。 `Category` が `categories` 内の文字列に一致しない製品は除外されます。`select` ステートメントは、`cat` と `prod` の両方からプロパティを取った新しい型をプロジェクトしています。 + +[!code-csharp[csrefQueryExpBasics#61](~/samples/snippets/csharp/concepts/linq/query-expression-basics_17.cs)] + +[into](../language-reference/keywords/into.md) キーワードを使用して `join` 操作の結果を一時変数に格納することにより、グループ結合を実行することもできます。 詳しくは、「[join 句](../language-reference/keywords/join-clause.md)」をご覧ください。 + #### let 句 - `let` 句は、式の結果 (メソッド呼び出しなど) を新しい範囲変数に格納するために使用します。 次の例では、`Split` よって返された文字列配列の最初の要素を、範囲変数 `firstName` に格納しています。 - - [!code-csharp[csrefQueryExpBasics#62](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_18.cs)] - - 詳しくは、「[let 句](../language-reference/keywords/let-clause.md)」をご覧ください。 - -### クエリ式内のサブクエリ - - クエリ句には、それ自体にクエリ式が含まれることがあります。これは、*サブクエリ*とも呼ばれます。 各サブクエリは、独自の `from` で始まります。この句は、最初の `from` 句と必ずしも同じデータ ソースを指している必要はありません。 たとえば、次のクエリは、select ステートメントで grouping 操作の結果を取得するために使用されるクエリ式を示しています。 - - [!code-csharp[csrefQueryExpBasics#63](../../../samples/snippets/csharp/concepts/linq/query-expression-basics_19.cs)] - - 詳しくは、「[方法: グループ化操作でサブクエリを実行する](perform-a-subquery-on-a-grouping-operation.md)」をご覧ください。 - -## 参照 - [C# プログラミング ガイド](../programming-guide/index.md) - [LINQ クエリ式](index.md) - [クエリ キーワード (LINQ)](../language-reference/keywords/query-keywords.md) - [標準クエリ演算子の概要](../programming-guide/concepts/linq/standard-query-operators-overview.md) +`let` 句は、式の結果 (メソッド呼び出しなど) を新しい範囲変数に格納するために使用します。 次の例では、`Split` よって返された文字列配列の最初の要素を、範囲変数 `firstName` に格納しています。 + +[!code-csharp[csrefQueryExpBasics#62](~/samples/snippets/csharp/concepts/linq/query-expression-basics_18.cs)] + +詳しくは、「[let 句](../language-reference/keywords/let-clause.md)」をご覧ください。 + +### クエリ式内のサブクエリ + +クエリ句には、それ自体にクエリ式が含まれることがあります。これは、*サブクエリ*とも呼ばれます。 各サブクエリは、独自の `from` で始まります。この句は、最初の `from` 句と必ずしも同じデータ ソースを指している必要はありません。 たとえば、次のクエリは、select ステートメントで grouping 操作の結果を取得するために使用されるクエリ式を示しています。 + +[!code-csharp[csrefQueryExpBasics#63](~/samples/snippets/csharp/concepts/linq/query-expression-basics_19.cs)] + +詳しくは、「[方法: グループ化操作でサブクエリを実行する](perform-a-subquery-on-a-grouping-operation.md)」をご覧ください。 + +## 関連項目 + +[C# プログラミング ガイド](../programming-guide/index.md) +[統合言語クエリ (LINQ)](index.md) +[クエリ キーワード (LINQ)](../language-reference/keywords/query-keywords.md) +[標準クエリ演算子の概要](../programming-guide/concepts/linq/standard-query-operators-overview.md) \ No newline at end of file diff --git a/docs/csharp/linq/write-linq-queries.md b/docs/csharp/linq/write-linq-queries.md index 4a139bc3fef..b7fd7562239 100644 --- a/docs/csharp/linq/write-linq-queries.md +++ b/docs/csharp/linq/write-linq-queries.md @@ -1,89 +1,86 @@ --- -title: C# での LINQ クエリの作成 -description: クエリの記述方法について説明します。 -ms.date: 12/1/2016 -ms.assetid: 30703f79-cf3a-4d02-b892-c95d58a1d9ed -ms.openlocfilehash: a9683dbf3c4101829054477824ccc7135f20f535 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33288838" +title: C# での LINQ クエリの作成 +description: C# で LINQ クエリを作成する方法について説明します。 +ms.date: 12/1/2016 +ms.assetid: 30703f79-cf3a-4d02-b892-c95d58a1d9ed +ms.openlocfilehash: 5003d1a5e15e17bea4204941d1c43895e3fb91f4 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37403935" --- -# C# での LINQ クエリの作成 - -このトピックでは、C# で LINQ クエリを記述できる 3 つの方法について説明します。 - -1. クエリ構文を使用する。 - -2. メソッド構文を使用する。 - -3. クエリ構文とメソッド構文を組み合わせて使用する。 - - 以下の例では、上記の各アプローチを使用したシンプルな LINQ クエリを示します。 一般に、可能であれば常に (1) を使用し、(2) と (3) は必要に応じて使用するというのがルールになっています。 - +# C# での LINQ クエリの作成 # + +この記事では、C# で LINQ クエリを作成できる 3 つの方法を示しています。 + +1. クエリ構文を使用する。 + +2. メソッド構文を使用する。 + +3. クエリ構文とメソッド構文を組み合わせて使用する。 + +以下の例では、上記の各アプローチを使用したシンプルな LINQ クエリを示します。 一般に、可能であれば常に (1) を使用し、(2) と (3) は必要に応じて使用するというのがルールになっています。 + > [!NOTE] -> これらのクエリでは、シンプルなメモリ内コレクションに対して操作を実行します。ただし、基本的な構文は、LINQ to Entities および LINQ to XML で使用されるのと同じものです。 - -## 例 - -## クエリ構文 - ほとんどのクエリ記述については、*クエリの構文*を使用して*クエリ式*を作成することをお勧めします。 次の例は、3 つのクエリ式を示しています。 1 つ目のクエリ式は、`where` 句を使用した条件を適用することで、結果をフィルター処理または制限する方法を示しています。 このクエリは、値が 7 より大きいか、または 3 より小さいソース シーケンス内のすべての要素を返します。 2 つ目の式は、返された結果を並べ替える方法を示しています。 3 つ目の式は、キーに基づいて結果をグループ化する方法を示しています。 このクエリは、単語の頭文字に基づいて 2 つのグループを返します。 - - [!code-csharp[csProgGuideLINQ#5](../../../samples/snippets/csharp/concepts/linq/how-to-write-linq-queries_1.cs)] - - クエリの型が であることに注意してください。 これらのクエリはすべて、次の例で示すように、`var` を使用しても記述できます。 - - `var query = from num in numbers...` - - 上記の各例では、`foreach` ステートメントまたはその他のステートメントでクエリ変数を反復処理するまで、クエリは実際には実行されません。 詳しくは、「[LINQ クエリの概要](../programming-guide/concepts/linq/introduction-to-linq-queries.md)」をご覧ください。 - -## 例 - -## メソッド構文 - 一部のクエリ操作は、メソッド呼び出しとして表す必要があります。 このようなメソッドで最も一般的なものは、 のような単一の数値を返すメソッドです。 これらのメソッドは、単一の値のみを表し、追加のクエリ操作のソースとしては使用できないため、常に、どのクエリよりも後に呼び出す必要があります。 次の例は、クエリ式でのメソッド呼び出しを示したものです。 - - [!code-csharp[csProgGuideLINQ#6](../../../samples/snippets/csharp/concepts/linq/how-to-write-linq-queries_2.cs)] - -## 例 - メソッドに Action または Func パラメーターがある場合、それらは[ラムダ](../programming-guide/statements-expressions-operators/lambda-expressions.md)式の形式で提供されます。次に例を示します。 - - [!code-csharp[csProgGuideLINQ#7](../../../samples/snippets/csharp/concepts/linq/how-to-write-linq-queries_3.cs)] - - 上記のクエリでは Query #4 だけが直ちに実行されます。 これは、それがジェネリック コレクションではなく、単一値を返すためです。 メソッド自体は、値を計算するために `foreach` を使用する必要があります。 - - 上記の各クエリは、[var](../language-reference/keywords/var.md) による暗黙的型指定を使用しても記述できます。次に例を示します。 - - [!code-csharp[csProgGuideLINQ#8](../../../samples/snippets/csharp/concepts/linq/how-to-write-linq-queries_4.cs)] - -## 例 - -## クエリとメソッド構文の併用 - この例では、クエリ句の結果に対してメソッド構文を使用する方法を示します。 方法は、クエリ式をかっこで囲み、ドット演算子を適用して、メソッドを呼び出すだけです。 次の例では、Query #7 は、値が 3 ~ 7 である数値のカウントを返します。 ただし一般的には、メソッド呼び出しの結果の格納には、2 番目の変数を使うほうが賢明です。 この方法のほうが、クエリをクエリ結果と混同する恐れがありません。 - - [!code-csharp[csProgGuideLINQ#9](../../../samples/snippets/csharp/concepts/linq/how-to-write-linq-queries_5.cs)] - - Query #7 はコレクションではなく単一の値を返すので、クエリはすぐに実行されます。 - - 上記のクエリは、`var` による暗黙的型指定を使用しても記述できます。次に例を示します。 - -```csharp -var numCount = (from num in numbers... -``` - - 次のように、メソッド構文で記述することもできます。 - -```csharp -var numCount = numbers.Where(n => n < 3 || n > 7).Count(); -``` - - 次のように、明示的な型指定を使用して記述することもできます。 - -```csharp -int numCount = numbers.Where(n => n < 3 || n > 7).Count(); -``` - -## 参照 - [チュートリアル: C# でのクエリの作成](../programming-guide/concepts/linq/walkthrough-writing-queries-linq.md) - [LINQ クエリ式](index.md) - [where 句](../language-reference/keywords/where-clause.md) +> これらのクエリでは、シンプルなメモリ内コレクションに対して操作を実行します。ただし、基本的な構文は、LINQ to Entities および LINQ to XML で使用されるのと同じものです。 + +## 例 - クエリ構文 + +ほとんどのクエリ記述については、*クエリの構文*を使用して*クエリ式*を作成することをお勧めします。 次の例は、3 つのクエリ式を示しています。 1 つ目のクエリ式は、`where` 句を使用した条件を適用することで、結果をフィルター処理または制限する方法を示しています。 このクエリは、値が 7 より大きいか、または 3 より小さいソース シーケンス内のすべての要素を返します。 2 つ目の式は、返された結果を並べ替える方法を示しています。 3 つ目の式は、キーに基づいて結果をグループ化する方法を示しています。 このクエリは、単語の頭文字に基づいて 2 つのグループを返します。 + +[!code-csharp[csProgGuideLINQ#5](~/samples/snippets/csharp/concepts/linq/how-to-write-linq-queries_1.cs)] + +クエリの型が であることに注意してください。 これらのクエリはすべて、次の例で示すように、`var` を使用しても記述できます。 + +`var query = from num in numbers...` + +上記の各例では、`foreach` ステートメントまたはその他のステートメントでクエリ変数を反復処理するまで、クエリは実際には実行されません。 詳しくは、「[LINQ クエリの概要](../programming-guide/concepts/linq/introduction-to-linq-queries.md)」をご覧ください。 + +## 例 - メソッド構文 + +一部のクエリ操作は、メソッド呼び出しとして表す必要があります。 このようなメソッドで最も一般的なものは、 のような単一の数値を返すメソッドです。 これらのメソッドは、単一の値のみを表し、追加のクエリ操作のソースとしては使用できないため、常に、どのクエリよりも後に呼び出す必要があります。 次の例は、クエリ式でのメソッド呼び出しを示したものです。 + +[!code-csharp[csProgGuideLINQ#6](~/samples/snippets/csharp/concepts/linq/how-to-write-linq-queries_2.cs)] + +メソッドに Action または Func パラメーターがある場合、それらは[ラムダ](../programming-guide/statements-expressions-operators/lambda-expressions.md)式の形式で提供されます。次に例を示します。 + +[!code-csharp[csProgGuideLINQ#7](~/samples/snippets/csharp/concepts/linq/how-to-write-linq-queries_3.cs)] + +上記のクエリでは Query #4 だけが直ちに実行されます。 これは、それがジェネリック コレクションではなく、単一値を返すためです。 メソッド自体は、値を計算するために `foreach` を使用する必要があります。 + +上記の各クエリは、[var](../language-reference/keywords/var.md) による暗黙的型指定を使用しても記述できます。次に例を示します。 + +[!code-csharp[csProgGuideLINQ#8](~/samples/snippets/csharp/concepts/linq/how-to-write-linq-queries_4.cs)] + +## 例 - クエリとメソッド構文の併用 + +この例では、クエリ句の結果に対してメソッド構文を使用する方法を示します。 方法は、クエリ式をかっこで囲み、ドット演算子を適用して、メソッドを呼び出すだけです。 次の例では、Query #7 は、値が 3 ~ 7 である数値のカウントを返します。 ただし一般的には、メソッド呼び出しの結果の格納には、2 番目の変数を使うほうが賢明です。 この方法のほうが、クエリをクエリ結果と混同する恐れがありません。 + +[!code-csharp[csProgGuideLINQ#9](~/samples/snippets/csharp/concepts/linq/how-to-write-linq-queries_5.cs)] + +Query #7 はコレクションではなく単一の値を返すので、クエリはすぐに実行されます。 + +上記のクエリは、`var` による暗黙的型指定を使用しても記述できます。次に例を示します。 + +```csharp +var numCount = (from num in numbers... +``` + +次のように、メソッド構文で記述することもできます。 + +```csharp +var numCount = numbers.Where(n => n < 3 || n > 7).Count(); +``` + +次のように、明示的な型指定を使用して記述することもできます。 + +```csharp +int numCount = numbers.Where(n => n < 3 || n > 7).Count(); +``` + +## 関連項目 + +[チュートリアル: C# でのクエリの作成](../programming-guide/concepts/linq/walkthrough-writing-queries-linq.md) +[統合言語クエリ (LINQ)](index.md) +[where 句](../language-reference/keywords/where-clause.md) \ No newline at end of file diff --git a/docs/csharp/programming-guide/arrays/passing-arrays-as-arguments.md b/docs/csharp/programming-guide/arrays/passing-arrays-as-arguments.md index 7ae7eb85ba1..cc4ef303a3a 100644 --- a/docs/csharp/programming-guide/arrays/passing-arrays-as-arguments.md +++ b/docs/csharp/programming-guide/arrays/passing-arrays-as-arguments.md @@ -1,64 +1,64 @@ --- -title: 引数としての配列の受け渡し (C# プログラミング ガイド) -ms.date: 07/20/2015 -helpviewer_keywords: -- arrays [C#], passing as arguments -ms.assetid: f3a0971e-c87c-4a1f-8262-bc0a3b712772 -ms.openlocfilehash: d863cdc33a8a1a844aabbea9ba5876614e6e8dba -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33315517" +title: 引数としての配列の受け渡し (C# プログラミング ガイド) +ms.date: 07/05/2018 +helpviewer_keywords: +- arrays [C#], passing as arguments +ms.assetid: f3a0971e-c87c-4a1f-8262-bc0a3b712772 +ms.openlocfilehash: 0289297be9d7b4989cc95d2b50b92dae9ee831f7 +ms.sourcegitcommit: 2d8b7488d94101b534ca3e9780b1c1e840233405 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/23/2018 +ms.locfileid: "39199232" --- # 引数としての配列の受け渡し (C# プログラミング ガイド) -配列は、引数としてメソッド パラメーターに渡すことができます。 配列は参照型であるため、メソッドは要素の値を変更できます。 - -## 1 次元配列を引数として渡す - 初期化された 1 次元配列をメソッドに渡すことができます。 たとえば、次のステートメントは、配列を print メソッドに送信します。 - - [!code-csharp[csProgGuideArrays#34](../../../csharp/programming-guide/arrays/codesnippet/CSharp/passing-arrays-as-arguments_1.cs)] - - 次のコードは、print メソッドの実装の一部を示しています。 - - [!code-csharp[csProgGuideArrays#33](../../../csharp/programming-guide/arrays/codesnippet/CSharp/passing-arrays-as-arguments_2.cs)] - - 次の例に示すように、一度に新しい配列を初期化して渡すことができます。 - - [!code-csharp[CsProgGuideArrays#35](../../../csharp/programming-guide/arrays/codesnippet/CSharp/passing-arrays-as-arguments_3.cs)] - -## 例 - -### 説明 - 次の例では、文字列の配列が初期化され、引数として文字列の `PrintArray` メソッドに渡されます。 このメソッドは、配列の要素を表示します。 次に、値渡しで配列引数を送信することで配列要素の変更が妨げられないことを示すため、メソッド `ChangeArray` と `ChangeArrayElement` が呼び出されます。 - -### コード - [!code-csharp[csProgGuideArrays#30](../../../csharp/programming-guide/arrays/codesnippet/CSharp/passing-arrays-as-arguments_4.cs)] - -## 多次元配列を引数として渡す - 1 次元配列を渡すのと同じ方法で、初期化された多次元配列をメソッドに渡します。 - - [!code-csharp[csProgGuideArrays#41](../../../csharp/programming-guide/arrays/codesnippet/CSharp/passing-arrays-as-arguments_5.cs)] - - 次のコードに、2 次元配列を引数として受け取る print メソッドの宣言の一部を示します。 - - [!code-csharp[csProgGuideArrays#36](../../../csharp/programming-guide/arrays/codesnippet/CSharp/passing-arrays-as-arguments_6.cs)] - - 次の例に示すように、一度に新しい配列を初期化して渡すことができます。 - - [!code-csharp[csProgGuideArrays#32](../../../csharp/programming-guide/arrays/codesnippet/CSharp/passing-arrays-as-arguments_7.cs)] - -## 例 - -### 説明 - 次の例では、整数の 2 次元配列が初期化され、`Print2DArray` メソッドに渡されます。 このメソッドは、配列の要素を表示します。 - -### コード - [!code-csharp[csProgGuideArrays#31](../../../csharp/programming-guide/arrays/codesnippet/CSharp/passing-arrays-as-arguments_8.cs)] - -## 参照 - [C# プログラミング ガイド](../../../csharp/programming-guide/index.md) - [配列](../../../csharp/programming-guide/arrays/index.md) - [1 次元配列](../../../csharp/programming-guide/arrays/single-dimensional-arrays.md) - [多次元配列](../../../csharp/programming-guide/arrays/multidimensional-arrays.md) - [ジャグ配列](../../../csharp/programming-guide/arrays/jagged-arrays.md) + +配列は、引数としてメソッド パラメーターに渡すことができます。 配列は参照型であるため、メソッドは要素の値を変更できます。 + +## 1 次元配列を引数として渡す + +初期化された 1 次元配列をメソッドに渡すことができます。 たとえば、次のステートメントは、配列を print メソッドに送信します。 + +[!code-csharp[csProgGuideArrays#34](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#34)] + +次のコードは、print メソッドの実装の一部を示しています。 + +[!code-csharp[csProgGuideArrays#33](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#33)] + +次の例に示すように、一度に新しい配列を初期化して渡すことができます。 + +[!code-csharp[CsProgGuideArrays#35](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#35)] + +### 例 + +次の例では、文字列の配列が初期化され、引数として文字列の `DisplayArray` メソッドに渡されます。 このメソッドは、配列の要素を表示します。 次に、`ChangeArray` メソッドで配列の要素を反転させた後、`ChangeArrayElements` メソッドで配列の最初の 3 つの要素を変更します。 各メソッドから戻った後、`DisplayArray` メソッドで、配列を値で渡すと配列要素の変更が禁止されないことを示します。 + +[!code-csharp[csProgGuideArrays#30](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/ArrayExample.cs)] + +## 多次元配列を引数として渡す + +1 次元配列を渡すのと同じ方法で、初期化された多次元配列をメソッドに渡します。 + +[!code-csharp[csProgGuideArrays#41](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#41)] + +次のコードに、2 次元配列を引数として受け取る print メソッドの宣言の一部を示します。 + +[!code-csharp[csProgGuideArrays#36](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#36)] + +次の例に示すように、一度に新しい配列を初期化して渡すことができます。 + +[!code-csharp[csProgGuideArrays#32](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#32)] + +### 例 + +次の例では、整数の 2 次元配列が初期化され、`Print2DArray` メソッドに渡されます。 このメソッドは、配列の要素を表示します。 + +[!code-csharp[csProgGuideArrays#31](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#31)] + +## 関連項目 + +[C# プログラミング ガイド](../index.md) +[配列](index.md) +[1 次元配列](single-dimensional-arrays.md) +[多次元配列](multidimensional-arrays.md) +[ジャグ配列](jagged-arrays.md) \ No newline at end of file diff --git a/docs/csharp/programming-guide/classes-and-structs/local-functions.md b/docs/csharp/programming-guide/classes-and-structs/local-functions.md index 6c9186c28af..25f8634cc7f 100644 --- a/docs/csharp/programming-guide/classes-and-structs/local-functions.md +++ b/docs/csharp/programming-guide/classes-and-structs/local-functions.md @@ -1,16 +1,16 @@ --- -title: ローカル関数 (C# プログラミング ガイド) -ms.date: 06/14/2017 -helpviewer_keywords: -- local functions [C#] -author: rpetrusha -ms.author: ronpet -ms.openlocfilehash: 208ac3d4a7b803dd081edfd9f5227a779f7cf211 -ms.sourcegitcommit: fc70fcb9c789b6a4aefcdace46f3643fd076450f -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/06/2018 -ms.locfileid: "34805621" +title: ローカル関数 (C# プログラミング ガイド) +ms.date: 06/14/2017 +helpviewer_keywords: +- local functions [C#] +author: rpetrusha +ms.author: ronpet +ms.openlocfilehash: 2f21dd80de8f9df612ab460b9375bf5c1dfae1ce +ms.sourcegitcommit: 702d5ffc6e733b6c4ded85bf1c92e2293638ee9a +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/04/2018 +ms.locfileid: "37792310" --- # ローカル関数 (C# プログラミング ガイド) diff --git a/docs/csharp/programming-guide/concepts/async/async-return-types.md b/docs/csharp/programming-guide/concepts/async/async-return-types.md index 45272f65d4b..9e7f5802e72 100644 --- a/docs/csharp/programming-guide/concepts/async/async-return-types.md +++ b/docs/csharp/programming-guide/concepts/async/async-return-types.md @@ -1,13 +1,13 @@ --- -title: 非同期の戻り値の型 (C#) -ms.date: 05/29/2017 -ms.assetid: ddb2539c-c898-48c1-ad92-245e4a996df8 -ms.openlocfilehash: 07aefcf3149b2210e3dc97713647fa3a0133a535 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33334185" +title: 非同期の戻り値の型 (C#) +ms.date: 05/29/2017 +ms.assetid: ddb2539c-c898-48c1-ad92-245e4a996df8 +ms.openlocfilehash: 02e3cdd433d5d6d4d58667d56592b9fc2bf374c4 +ms.sourcegitcommit: dc02d7d95f1e3efcc7166eaf431b0ec0dc9d8dca +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/02/2018 +ms.locfileid: "37143558" --- # 非同期の戻り値の型 (C#) 非同期メソッドには、次の戻り値の型があります。 @@ -24,7 +24,7 @@ ms.locfileid: "33334185" それぞれの戻り値の型は、次のセクションの 1 つで確認でき、トピックの最後で 3 種類のすべてを使用する例を参照できます。 -## Task(T) 型 +## Task\ の戻り値の型 `TResult` 型のオペランドを持つ [return](../../../../csharp/language-reference/keywords/return.md) (C#) ステートメントを含む非同期メソッドには、 戻り値の型が使用されます。 次の例では、`GetLeisureHours` 非同期メソッドには整数を返す `return` ステートメントが含まれます。 そのため、メソッド宣言では、戻り値の型を `Task` と指定する必要があります。 非同期メソッドは、文字列を返す操作を表すプレースホルダーです。 @@ -60,13 +60,13 @@ ms.locfileid: "33334185" void を返す非同期メソッドの呼び出し元は、メソッドがスローする例外をキャッチすることはできません。そのようなハンドルされない例外によって、アプリケーションが失敗する可能性が高くなります。 または を返す非同期メソッドで例外が発生すると、例外は返されたタスクに格納され、タスクが待機するときに再スローされます。 したがって、例外を生成する場合がある非同期メソッドは または の戻り値の型を持つこと、またメソッドの呼び出しが待機することを確認します。 -非同期のメソッドで例外をキャッチする方法の詳細については、「[try-catch](../../../../csharp/language-reference/keywords/try-catch.md)」を参照してください。 +非同期メソッドで例外をキャッチする方法の詳細については、「[try-catch](../../../language-reference/keywords/try-catch.md)」トピックの「[非同期メソッドの例外](../../../language-reference/keywords/try-catch.md#exceptions-in-async-methods)」を参照してください。 次の例では、非同期のイベント ハンドラーを定義します。 [!code-csharp[return-value](../../../../../samples/snippets/csharp/programming-guide/async/async-returns3.cs)] -## 一般化された async の戻り値の型と ValueTask +## 一般化された非同期の戻り値の型と ValueTask\ C# 7.0 以降、非同期メソッドで、アクセス可能な `GetAwaiter` メソッドを持つ任意の型を返すことができます。 diff --git a/docs/csharp/programming-guide/concepts/threading/parameters-and-return-values-for-multithreaded-procedures.md b/docs/csharp/programming-guide/concepts/threading/parameters-and-return-values-for-multithreaded-procedures.md new file mode 100644 index 00000000000..3f5d4704034 --- /dev/null +++ b/docs/csharp/programming-guide/concepts/threading/parameters-and-return-values-for-multithreaded-procedures.md @@ -0,0 +1,127 @@ +--- +title: マルチスレッド プロシージャのパラメーターと戻り値 (C#) +ms.date: 07/20/2015 +ms.assetid: ba63c30c-d9f0-4962-b5c7-9d83ba851e6a +ms.openlocfilehash: 218e297d192d37d55ff391045342262d7bf66a0c +ms.sourcegitcommit: 59b51cd7c95c75be85bd6ef715e9ef8c85720bac +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/06/2018 +ms.locfileid: "37875131" +--- +# マルチスレッド プロシージャのパラメーターと戻り値 (C#) +マルチスレッド アプリケーションでの値の受け渡しは複雑です。それは、引数を受け取らず値を返さないプロシージャへの参照をスレッド クラスのコンストラクターに渡す必要があるためです。 以下のセクションでは、異なるスレッドのプロシージャからパラメーターを指定して値を返す単純な方法を示します。 + +## マルチスレッド プロシージャのパラメーターの指定 + マルチスレッド メソッドの呼び出しにパラメーターを指定する最良の方法は、クラスにターゲット メソッドをラップし、新規スレッドのパラメーターとして機能するフィールドをそのクラスに対して定義することです。 この方法の利点は、新規スレッドを開始するたびに独自のパラメーターでクラスの新規インスタンスを作成できることです。 たとえば、次のコードに示すように三角形の面積を計算する関数があるとします。 + +```csharp +double CalcArea(double Base, double Height) +{ + return 0.5 * Base * Height; +} +``` + + 次に示すように、`CalcArea` 関数をラップして入力パラメーターを格納するフィールドを作成するクラスを記述できます。 + +```csharp +class AreaClass +{ + public double Base; + public double Height; + public double Area; + public void CalcArea() + { + Area = 0.5 * Base * Height; + MessageBox.Show("The area is: " + Area.ToString()); + } +} +``` + + `AreaClass` を使用するには、次のコードに示すように `AreaClass` オブジェクトを作成し、`Base` プロパティと `Height` プロパティを設定します。 + +```csharp +protected void TestArea() +{ + AreaClass AreaObject = new AreaClass(); + + System.Threading.Thread Thread = + new System.Threading.Thread(AreaObject.CalcArea); + AreaObject.Base = 30; + AreaObject.Height = 40; + Thread.Start(); +} +``` + + `TestArea` プロシージャは `CalcArea` メソッドの呼び出し後に `Area` フィールドの値を確認しないことに注意してください。 `CalcArea` は別のスレッドで実行されるため、`Thread.Start` を呼び出した直後に確認する場合は、`Area` フィールドが設定されているとは限りません。 次のセクションでは、マルチスレッド プロシージャから値を返す適切な方法について説明します。 + +## マルチスレッド プロシージャから値を返す + 異なるスレッドで実行されるプロシージャの場合、値を返す動作は複雑になります。プロシージャは関数にすることができず、`ByRef` 引数を使用できないからです。 値を返す最も簡単な方法は、 コンポーネントを使ってスレッドを管理し、タスクが完了したときにイベントを生成し、結果をイベント ハンドラーで処理することです。 + + 次の例では、別のスレッドで実行中のプロシージャからイベントを発生させて値を返します。 + +```csharp +class AreaClass2 +{ + public double Base; + public double Height; + public double CalcArea() + { + // Calculate the area of a triangle. + return 0.5 * Base * Height; + } +} + +private System.ComponentModel.BackgroundWorker BackgroundWorker1 + = new System.ComponentModel.BackgroundWorker(); + +private void TestArea2() +{ + InitializeBackgroundWorker(); + + AreaClass2 AreaObject2 = new AreaClass2(); + AreaObject2.Base = 30; + AreaObject2.Height = 40; + + // Start the asynchronous operation. + BackgroundWorker1.RunWorkerAsync(AreaObject2); +} + +private void InitializeBackgroundWorker() +{ + // Attach event handlers to the BackgroundWorker object. + BackgroundWorker1.DoWork += + new System.ComponentModel.DoWorkEventHandler(BackgroundWorker1_DoWork); + BackgroundWorker1.RunWorkerCompleted += + new System.ComponentModel.RunWorkerCompletedEventHandler(BackgroundWorker1_RunWorkerCompleted); +} + +private void BackgroundWorker1_DoWork( + object sender, + System.ComponentModel.DoWorkEventArgs e) +{ + AreaClass2 AreaObject2 = (AreaClass2)e.Argument; + // Return the value through the Result property. + e.Result = AreaObject2.CalcArea(); +} + +private void BackgroundWorker1_RunWorkerCompleted( + object sender, + System.ComponentModel.RunWorkerCompletedEventArgs e) +{ + // Access the result through the Result property. + double Area = (double)e.Result; + MessageBox.Show("The area is: " + Area.ToString()); +} +``` + + スレッド プールのスレッドにパラメーターと戻り値を提供するには、 メソッドの省略可能な `ByVal` 状態オブジェクト変数を使用します。 スレッド タイマーのスレッドもこの目的で状態オブジェクトをサポートしています。 スレッド プールとスレッド タイマーの詳細については、「[スレッド プール (C#)](../../../../csharp/programming-guide/concepts/threading/thread-pooling.md)」と「[タイマー](../../../../standard/threading/timers.md)」を参照してください。 + +## 参照 + [チュートリアル: BackgroundWorker コンポーネントでのマルチスレッド (C#)](../../../../csharp/programming-guide/concepts/threading/walkthrough-multithreading-with-the-backgroundworker-component.md) + [スレッド プール (C#)](../../../../csharp/programming-guide/concepts/threading/thread-pooling.md) + [スレッドの同期 (C#)](../../../../csharp/programming-guide/concepts/threading/thread-synchronization.md) + [イベント](../../../../csharp/programming-guide/events/index.md) + [マルチスレッド アプリケーション (C#)](../../../../csharp/programming-guide/concepts/threading/multithreaded-applications.md) + [デリゲート](../../../../csharp/programming-guide/delegates/index.md) + [コンポーネントのマルチスレッド](http://msdn.microsoft.com/library/2fc31e68-fb71-4544-b654-0ce720478779) diff --git a/docs/csharp/programming-guide/exceptions/how-to-catch-a-non-cls-exception.md b/docs/csharp/programming-guide/exceptions/how-to-catch-a-non-cls-exception.md index 7a9996ffd6b..a529097549e 100644 --- a/docs/csharp/programming-guide/exceptions/how-to-catch-a-non-cls-exception.md +++ b/docs/csharp/programming-guide/exceptions/how-to-catch-a-non-cls-exception.md @@ -1,63 +1,52 @@ --- -title: '方法 : CLS 準拠でない例外をキャッチする' -ms.date: 07/20/2015 -helpviewer_keywords: -- exceptions [C#], non-CLS -ms.assetid: db4630b3-5240-471a-b3a7-c7ff6ab31e8d -ms.openlocfilehash: 6169f4b6de2efdfed0dbf43272d708c47b46dbca -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33340022" +title: '方法 : CLS 準拠でない例外をキャッチする' +ms.date: 07/20/2015 +helpviewer_keywords: +- exceptions [C#], non-CLS +ms.assetid: db4630b3-5240-471a-b3a7-c7ff6ab31e8d +ms.openlocfilehash: c3153da78e0c25d59da7b5d83bd33f8080c7fae8 +ms.sourcegitcommit: 2d8b7488d94101b534ca3e9780b1c1e840233405 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/23/2018 +ms.locfileid: "39198771" --- # 方法 : CLS 準拠でない例外をキャッチする -C++/CLI をはじめとする一部の .NET 言語では、 から派生していない例外をオブジェクトでスローすることができます。 このような例外は "*CLS 準拠でない例外*" や "*非例外*" と呼ばれています。 Visual C# では、CLS 準拠でない例外をスローすることはできませんが、それらをキャッチすることはできます。次の 2 とおりの方法があります。 +C++/CLI をはじめとする一部の .NET 言語では、 から派生していない例外をオブジェクトでスローすることができます。 このような例外は "*CLS 準拠でない例外*" や "*非例外*" と呼ばれています。 C# では、CLS 準拠でない例外をスローすることはできませんが、それらをキャッチすることはできます。次の 2 とおりの方法があります。 -- として `catch (Exception e)` ブロック内で。 +- `catch (RuntimeWrappedException e)` ブロック内で。 - Visual C# アセンブリの既定の動作上、CLS 準拠でない例外はラップされた例外としてキャッチされます。 元の例外にアクセスする必要がある場合 ( プロパティからアクセスできます)、このメソッドを利用します。 この方法で例外をキャッチする方法については、このトピックで後述します。 + Visual C# アセンブリの既定の動作上、CLS 準拠でない例外はラップされた例外としてキャッチされます。 元の例外にアクセスする必要がある場合 ( プロパティからアクセスできます)、このメソッドを利用します。 この方法で例外をキャッチする方法については、このトピックで後述します。 -- `catch (Exception)` ブロックまたは `catch (Exception e)` ブロックの後に置いた汎用的な catch ブロック (例外の型が指定されていない catch ブロック) 内でキャッチする。 +- 他のすべての `catch` ブロックの後に置いた汎用的な catch ブロック (例外の型が指定されていない catch ブロック) 内で。 この方法は、CLS 準拠でない例外への応答として何らかのアクション (ログ ファイルへの書き込みなど) を実行したい場合で、なおかつ例外情報にアクセスする必要がない場合に使用します。 既定では、すべての例外が共通言語ランタイムによってラップされます。 この動作を無効にするには、`[assembly: RuntimeCompatibilityAttribute(WrapNonExceptionThrows = false)]` というアセンブリ レベルの属性を (通常、AssemblyInfo.cs ファイル内の) コードに追加します。 ### CLS 準拠でない例外をキャッチするには -1. `catch(Exception e) block` 内で、`as` キーワードを利用し、`e` を にキャストできるかどうかテストします。 - -2. プロパティから元の例外にアクセスします。 +`catch(RuntimeWrappedException e)` ブロック内で、 プロパティから元の例外にアクセスします。 ## 例 - 次の例は、C++/CLR のクラス ライブラリからスローされた、CLS 準拠でない例外をキャッチする方法を示しています。 この例で、Visual C# クライアント コードは、スローされる例外の型が であることを事前に把握しています。 その型にコードからアクセスできる限り、 プロパティは元の型にキャストできます。 - -``` -// Class library written in C++/CLR. - ThrowNonCLS.Class1 myClass = new ThrowNonCLS.Class1(); - - try - { + 次の例では、C++/CLI で記述されたクラス ライブラリからスローされた、CLS 準拠でない例外をキャッチする方法を示します。 この例で、C# クライアント コードは、スローされる例外の型が であることを事前に把握しています。 その型にコードからアクセスできる限り、 プロパティは元の型にキャストできます。 + +```csharp +// Class library written in C++/CLI. +var myClass = new ThrowNonCLS.Class1(); + +try +{ // throws gcnew System::String( // "I do not derive from System.Exception!"); - myClass.TestThrow(); - } - - catch (Exception e) - { - RuntimeWrappedException rwe = e as RuntimeWrappedException; - if (rwe != null) - { - String s = rwe.WrappedException as String; - if (s != null) - { - Console.WriteLine(s); - } - } - else - { - // Handle other System.Exception types. - } - } + myClass.TestThrow(); +} +catch (RuntimeWrappedException e) +{ + String s = e.WrappedException as String; + if (s != null) + { + Console.WriteLine(s); + } +} ``` ## 参照 diff --git a/docs/csharp/programming-guide/statements-expressions-operators/expressions.md b/docs/csharp/programming-guide/statements-expressions-operators/expressions.md index c59aa838db8..af6ee7ae812 100644 --- a/docs/csharp/programming-guide/statements-expressions-operators/expressions.md +++ b/docs/csharp/programming-guide/statements-expressions-operators/expressions.md @@ -1,16 +1,16 @@ --- -title: 式 (C# プログラミング ガイド) -ms.date: 05/11/2017 -helpviewer_keywords: -- expressions [C#] -- C# language, expressions -ms.assetid: c7d8feb0-0e58-4f94-8bf6-4d070550a832 -ms.openlocfilehash: 830c68e6857e72fe19099753ba57a7e22491af2c -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33339658" +title: 式 (C# プログラミング ガイド) +ms.date: 05/11/2017 +helpviewer_keywords: +- expressions [C#] +- C# language, expressions +ms.assetid: c7d8feb0-0e58-4f94-8bf6-4d070550a832 +ms.openlocfilehash: bb70a7e3dfd8b274987bf68568004d785afd0ee1 +ms.sourcegitcommit: 60645077dc4b62178403145f8ef691b13ffec28e +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/10/2018 +ms.locfileid: "37936955" --- # 式 (C# プログラミング ガイド) *式*とは、1 つの値、オブジェクト、メソッド、または名前空間に評価できる、1 つ以上のオペランドと 0 個以上の演算子のシーケンスです。 式には、リテラル値、メソッドの呼び出し、演算子とそのオペランド、または*簡易名*を含めることができます。 単純な名前には、変数、型メンバー、メソッド パラメーター、名前空間、または型の名前を指定できます。 @@ -61,8 +61,9 @@ DoWork(); ## ラムダ式 ラムダ式は、名前がないが入力パラメーターおよび複数のステートメントを持つことができる "インライン メソッド" を表します。 LINQ では、メソッドに引数を渡すために広く使用されています。 ラムダ式は、使用されるコンテキストに応じて、デリゲートまたは式ツリーにコンパイルされます。 詳しくは、「[ラムダ式](../../../csharp/programming-guide/statements-expressions-operators/lambda-expressions.md)」をご覧ください。 -## 式ツリー - 式ツリーを使用すると、式をデータ構造体として表すことができます。 クエリ式を、SQL データベースなどの他のコンテキストで意味を持つコードに変換するために、LINQ プロバイダーにより広く使用されています。 詳細については、「[式ツリー](http://msdn.microsoft.com/library/fb1d3ed8-d5b0-4211-a71f-dd271529294b)」を参照してください。 +## 式ツリー + +式ツリーを使用すると、式をデータ構造体として表すことができます。 クエリ式を、SQL データベースなどの他のコンテキストで意味を持つコードに変換するために、LINQ プロバイダーにより広く使用されています。 詳しくは、「[式ツリー (C#)](../concepts/expression-trees/index.md)」をご覧ください。 ## 式本体の定義 diff --git a/docs/csharp/programming-guide/types/using-type-dynamic.md b/docs/csharp/programming-guide/types/using-type-dynamic.md index f3fe75fe675..c51833af9ea 100644 --- a/docs/csharp/programming-guide/types/using-type-dynamic.md +++ b/docs/csharp/programming-guide/types/using-type-dynamic.md @@ -1,16 +1,16 @@ --- -title: dynamic 型の使用 (C# プログラミング ガイド) -ms.date: 07/20/2015 -helpviewer_keywords: -- dynamic [C#], about dynamic type -- dynamic type [C#] -ms.assetid: 3828989d-c967-4a51-b948-857ebc8fdf26 -ms.openlocfilehash: 67eb39fd6f2077d2adf1d38d001e801b815d687d -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33336639" +title: dynamic 型の使用 (C# プログラミング ガイド) +ms.date: 07/20/2015 +helpviewer_keywords: +- dynamic [C#], about dynamic type +- dynamic type [C#] +ms.assetid: 3828989d-c967-4a51-b948-857ebc8fdf26 +ms.openlocfilehash: 296b9c80b4ea8b09e8efce71e3b388f7e453850b +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404377" --- # dynamic 型の使用 (C# プログラミング ガイド) [!INCLUDE[csharp_dev10_long](~/includes/csharp-dev10-long-md.md)] では、`dynamic` という新しい型が導入されています。 この型は静的な型ですが、`dynamic` 型のオブジェクトは静的な型チェックをバイパスします。 ほとんどの場合、`object` 型を使用する場合と同様に機能します。 コンパイル時には、`dynamic` として型指定された要素はあらゆる操作をサポートすると見なされます。 したがって、オブジェクトが COM API、IronPython などの動的言語、HTML ドキュメント オブジェクト モデル (DOM)、リフレクション、プログラムの他の場所のいずれから値を取得するのかを考慮する必要はありません。 ただし、コードが無効な場合には、実行時にエラーが検出されます。 @@ -27,7 +27,12 @@ ms.locfileid: "33336639" [!code-csharp[CsProgGuideTypes#51](../../../csharp/programming-guide/nullable-types/codesnippet/CSharp/using-type-dynamic_3.cs)] - 結果が `dynamic` でない操作として、`dynamic` から他の型への変換や、`dynamic` 型の引数を含むコンストラクター呼び出しがあります。 たとえば、次の宣言の `testInstance` の型は、`dynamic` ではなく、`ExampleClass` です。 + 結果が `dynamic` ではない操作を次に示します。 + +* `dynamic` から別の型への変換。 +* `dynamic` 型の引数を含むコンストラクターの呼び出し。 + +たとえば、次の宣言の `testInstance` の型は、`dynamic` ではなく、`ExampleClass` です。 [!code-csharp[CsProgGuideTypes#52](../../../csharp/programming-guide/nullable-types/codesnippet/CSharp/using-type-dynamic_4.cs)] diff --git a/docs/csharp/quick-starts/list-collection.yml b/docs/csharp/quick-starts/list-collection.yml index c41b942df4b..89de2acc4d3 100644 --- a/docs/csharp/quick-starts/list-collection.yml +++ b/docs/csharp/quick-starts/list-collection.yml @@ -1,4 +1,4 @@ -### YamlMime:Tutorial +### YamlMime:Tutorial title: C# のコレクション metadata: title: コレクションの対話形式チュートリアル - C# クイックスタート @@ -9,12 +9,12 @@ metadata: level: Beginner displayType: two-column interactive: csharp - ms.openlocfilehash: 79861f7a04939fafd77bd7a905b8fef0e94b8966 - ms.sourcegitcommit: 15109844229ade1c6449f48f3834db1b26907824 + ms.openlocfilehash: 70db30c1d6a3d193533119dd5a49be3b9315eaaf + ms.sourcegitcommit: 60645077dc4b62178403145f8ef691b13ffec28e ms.translationtype: HT ms.contentlocale: ja-JP - ms.lasthandoff: 05/07/2018 - ms.locfileid: "33805916" + ms.lasthandoff: 07/10/2018 + ms.locfileid: "37937012" items: - durationInMinutes: 1 content: > @@ -22,7 +22,7 @@ items: - title: リストを作成する durationInMinutes: 2 content: > - 対話型ウィンドウで次のコードを実行します。 そのためには、対話型ウィンドウで次のコード ブロックを入力し ("" を自分の名前に置き換えて)、**[実行]** をクリックします。 + 対話型ウィンドウで次のコードを実行します。 そのためには、対話型ウィンドウで次のコード ブロックを入力し (`` を自分の名前に置き換えて)、**[実行]** をクリックします。 ```csharp diff --git a/docs/csharp/tutorials/inheritance.md b/docs/csharp/tutorials/inheritance.md index 1097b265748..ef02c1fa1f7 100644 --- a/docs/csharp/tutorials/inheritance.md +++ b/docs/csharp/tutorials/inheritance.md @@ -1,16 +1,16 @@ --- -title: C# での継承 -description: C# ライブラリやアプリケーションでの継承の使用について学習します。 -author: rpetrusha -ms.author: ronpet -ms.date: 08/16/2017 -ms.assetid: aeb68c74-0ea0-406f-9fbe-2ce02d47ef31 -ms.openlocfilehash: 1476425594e55531fdb56de531ee61808dccd7db -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33365762" +title: C# での継承 +description: C# ライブラリやアプリケーションでの継承の使用について学習します。 +author: rpetrusha +ms.author: ronpet +ms.date: 07/05/2018 +ms.assetid: aeb68c74-0ea0-406f-9fbe-2ce02d47ef31 +ms.openlocfilehash: 646602c4bab311e6d6078378fe423741a1dd38e1 +ms.sourcegitcommit: 59b51cd7c95c75be85bd6ef715e9ef8c85720bac +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/06/2018 +ms.locfileid: "37875225" --- # C# と .NET での継承 @@ -33,7 +33,6 @@ ms.locfileid: "33365762" 1. [dotnet run](../../core/tools/dotnet-run.md) コマンドを入力して、例をコンパイルし実行します。 - ## 基礎知識: 継承とは何か *継承*とは、オブジェクト指向プログラミングの基本的な属性の 1 つです。 親クラスの動作を再利用 (継承)、拡張、または変更する子クラスを定義することができます。 メンバーの継承元となるクラスを、*基底クラス*と呼びます。 基底クラスのメンバーを継承するクラスを、*派生クラス*と呼びます。 @@ -99,7 +98,7 @@ public class B : A // Generates CS0534. } ``` -継承は、クラスとインターフェイスにのみ適用されます。 その他の種類のカテゴリ (構造体、デリゲート、および列挙型) は、継承をサポートしていません。 このため、次のようなコードをコンパイルしようとすると、コンパイラ エラー CS0527 "Type 'ValueType' in interface list is not an interface." ("インターフェイス リストの型 'ValueType' はインターフェイスではありません") が生成されます。 このエラー メッセージは、構造体が実装するインターフェイスを定義することはできても、継承はサポートされないことを示します。 +継承は、クラスとインターフェイスにのみ適用されます。 その他の種類のカテゴリ (構造体、デリゲート、および列挙型) は、継承をサポートしていません。 これらのルールのため、次の例のようなコードをコンパイルしようとすると、コンパイラ エラー CS0527 "インターフェイス リストの型 'ValueType' はインターフェイスではありません。" が生成されます。 このエラー メッセージは、構造体が実装するインターフェイスを定義することはできても、継承はサポートされないことを示します。 ```csharp using System; @@ -111,13 +110,13 @@ public struct ValueStructure : ValueType // Generates CS0527. ## 暗黙的な継承 -.NET 型システムの型はすべて、単一継承によって継承する型のほかに、 またはその派生型から暗黙的に継承します。 これにより、あらゆる型において共通の機能が使用可能となります。 +.NET 型システムの型はすべて、単一継承によって継承する型のほかに、 またはその派生型から暗黙的に継承します。 の共通の機能はあらゆる型で使用できます。 暗黙的な継承とはどのようなものか、新しいクラス `SimpleClass` を定義してみましょう。単純な空のクラス定義です。 [!code-csharp[Inheritance](../../../samples/snippets/csharp/tutorials/inheritance/simpleclass.cs#1)] -次に、リフレクション (型のメタデータを検査してその型の情報を取得できるもの) を使用して、`SimpleClass` 型に属するメンバーの一覧を取得します。 `SimpleClass` クラスにはメンバーをまだ定義していないにもかかわらず、この例の出力は、9 つのメンバーが存在することを示しています。 そのうち 1 つは、パラメーターなしの (既定の) コンストラクターで、C# コンパイラによって `SimpleClass` 型に自動的に提供されるものです。 あとの 8 つは のメンバーで、この型から、.NET 型システムのすべてのクラスとインターフェイスが最終的に暗黙的に継承します。 +次に、リフレクション (型のメタデータを検査して、その型の情報を取得できるもの) を使用して、`SimpleClass` 型に属するメンバーの一覧を取得します。 `SimpleClass` クラスにはメンバーをまだ定義していないにもかかわらず、この例の出力は、9 つのメンバーが存在することを示しています。 これらのメンバーのうちの 1 つは、パラメーターなし (既定) のコンストラクターで、C# コンパイラによって `SimpleClass` 型に自動的に提供されるものです。 あとの 8 つは のメンバーで、この型から、.NET 型システムのすべてのクラスとインターフェイスが最終的に暗黙的に継承します。 [!code-csharp[Inheritance](../../../samples/snippets/csharp/tutorials/inheritance/simpleclass.cs#2)] @@ -171,27 +170,29 @@ public struct ValueStructure : ValueType // Generates CS0527. ### 基底 Publication クラス -`Publication` クラスを設計するにあたり、設計について決まりをいくつか作る必要があります。 +`Publication` クラスを設計するにあたり、次のように、設計についていくつか決定する必要があります。 - どのメンバーを基底クラス `Publication` に含めるか、`Publication` メンバーがメソッドの実装を提供するかどうか、`Publication` をその派生クラスのテンプレートとなる抽象基底クラスとするかどうか。 - ここで、`Publication` クラスはメソッドの実装を提供します。 「[抽象基底クラスとその派生クラスの設計](#abstract)」セクションには、抽象基底クラスを使用して、派生クラスが上書きする必要があるメソッドを定義する例が含まれています。 派生クラスは、その派生型に適した任意の実装を提供することができます。 + ここで、`Publication` クラスはメソッドの実装を提供します。 「[抽象基底クラスとその派生クラスの設計](#abstract)」セクションには、抽象基底クラスを使用して、派生クラスがオーバーライドする必要があるメソッドを定義する例が含まれています。 派生クラスは、その派生型に適した任意の実装を提供することができます。 - コードを再利用する機能 (つまり、複数の派生クラスが基底クラスのメソッドの宣言と実装を共有し、それらをオーバーライドする必要がないこと) は、非抽象基底クラスの利点です。 そこで、コードが `Publication` 型の複数または非常に特殊化されたものによって共有される可能性が高い場合は、メンバーを `Publication` に追加します。 これが効率的にできていないと、基底クラスでの単一の実装で済むところを、派生クラスでほぼ同一のメンバーの実装を行わなければいけないことなります。 複数の箇所で重複するコードを保守する必要が生じ、バグを引き起こす元となりえます。 + コードを再利用する機能 (つまり、複数の派生クラスが基底クラスのメソッドの宣言と実装を共有し、それらをオーバーライドする必要がないこと) は、非抽象基底クラスの利点です。 そこで、コードが `Publication` 型の複数または非常に特殊化されたものによって共有される可能性が高い場合は、メンバーを `Publication` に追加します。 基底クラスの実装を効率的に提供できていないと、基底クラスでの単一の実装で済むところを、派生クラスでほぼ同一のメンバーの実装を行わなければいけないことになります。 複数の箇所で重複するコードを保守する必要が生じ、バグを引き起こす元となりえます。 コードの再利用を最大化し、同時に論理的で直感的な継承階層を作成するために、`Publication` クラスには必ず、すべてもしくはほとんどの出版物に共通したデータと機能のみを含めるようにします。 そして派生クラスは、それ自身が表す特定の種類の出版物に固有のメンバーを実装します。 - クラス階層をどの程度まで拡張すべきか。 1 つの基底クラスと 1 つまたは複数の派生クラスではなく、3 つ以上のクラス階層を作るかどうか。 たとえば、`Publication` は `Periodical` の基底クラスになり得ますが、この Periodical は `Magazine`、`Journal`、および `Newspaper` の基底クラスです。 - この例では、`Publication` クラスと 1 つの派生クラス `Book` という単純な階層構造を使用します。 この例を拡張すると、`Magazine` や `Article` など、`Publication` から派生するクラスを簡単に追加で多く作成できます。 + この例では、`Publication` クラスと 1 つの派生クラス `Book` という小さな階層を使用します。 この例を拡張すると、`Magazine` や `Article` など、`Publication` から派生するクラスを簡単に追加で多く作成できます。 + +- 基底クラスのインスタンス化に意味があるのか。 意味がなければ、そのクラスには [abstract](../language-reference/keywords/abstract.md) キーワードを適用します。 それ以外の場合、`Publication` クラスはそのクラス コンストラクターを呼び出すことによってインスタンス化することができます。 `abstract` キーワードでマークされたクラスを、そのクラス コンストラクターへの直接呼び出しによってインスタンス化しようとすると、C# コンパイラはエラー CS0144 "Cannot create an instance of the abstract class or interface." ("抽象クラスまたはインターフェイスのインスタンスを作成できません") を生成します。 リフレクションを使用してクラスをインスタンス化しようとすると、そのリフレクション メソッドは をスローします。 -- 基底クラスのインスタンス化に意味があるのか。 意味がなければ、そのクラスには [abstract](../language-reference/keywords/abstract.md) キーワードを適用します。 `abstract` キーワードでマークされたクラスを、そのクラス コンストラクターへの直接呼び出しによってインスタンス化しようとすると、C# コンパイラはエラー CS0144 "Cannot create an instance of the abstract class or interface." ("抽象クラスまたはインターフェイスのインスタンスを作成できません") を生成します。 リフレクションを使用してクラスをインスタンス化しようとすると、そのリフレクション メソッドは をスローします。 それ以外の場合、`Publication` クラスはそのクラス コンストラクターを呼び出すことによってインスタンス化することができます。 + 既定では、基底クラスはそのクラス コンストラクターを呼び出すことによってインスタンス化することができます。 クラス コンストラクターを明示的に定義する必要はありません。 基底クラスのソース コード内に存在しない場合、C# コンパイラは自動的に既定の (パラメーターなしの) コンストラクターを提供します。 - 既定では、基底クラスはそのクラス コンストラクターを呼び出すことによってインスタンス化することができます。 なお、クラス コンストラクターを明示的に定義する必要はありません。 基底クラスのソース コード内に存在しない場合、C# コンパイラは自動的に既定の (パラメーターなしの) コンストラクターを提供します。 + この例では、`Publication` クラスを [abstract](../language-reference/keywords/abstract.md) としてマークして、インスタンス化できないようにします。 `abstract` メソッドなしの `abstract` クラスは、このクラスが、いくつかの具象クラス (`Book`、`Journal` など) で共有される抽象概念を表すことを示します。 - この例では、`Publication` クラスを [abstract](../language-reference/keywords/abstract.md) としてマークして、インスタンス化できないようにします。 +- 派生クラスで、特定のメンバーの基底クラス実装を継承する必要があるかどうか、基底クラス実装をオーバーライドするオプションがあるかどうか、または実装を提供する必要があるかどうか。 [abstract](../language-reference/keywords/abstract.md) キーワードを使用して、派生クラスで実装を提供するように強制します。 [virtual](../language-reference/keywords/virtual.md) キーワードを使用して、派生クラスによる基底クラス メソッドのオーバーライドを許可します。 既定では、基底クラスで定義されているメソッドはオーバーライド*できません*。 -- 派生クラスで、特定のメンバーの基底クラス実装を継承する必要があるかどうか、または基底クラス実装をオーバーライドするオプションがあるかどうか。 [virtual](../language-reference/keywords/virtual.md) キーワードを使用して、派生クラスによる基底クラス メソッドのオーバーライドを許可する必要があります。 既定では、基底クラスで定義されているメソッドはオーバーライド*できません*。 + `Publication` クラスには `abstract` メソッドはありませんが、クラス自体が `abstract` になります。 - 派生クラスが継承階層内の最後のクラスを表していて、それ自体が追加の派生クラスの基底クラスとして使用できないかどうか。 既定では、どのクラスも基底クラスとして使用できます。 [sealed](../language-reference/keywords/sealed.md) キーワードを適用すると、クラスが追加クラスの基底クラスとして使用できないことを示すことができます。 sealed クラスからの派生を試みると、コンパイラ エラー CS0509 "cannot derive from sealed type " ("シール型 typeName から派生することができません") が生成されます。 @@ -203,7 +204,7 @@ public struct ValueStructure : ValueType // Generates CS0527. - コンストラクター - `Publication` クラスは `abstract` なので、次のようなコードから直接インスタンス化することはできません。 + `Publication` クラスは `abstract` なので、次の例のようなコードから直接インスタンス化することはできません。 ```csharp var publication = new Publication("Tiddlywinks for Experts", "Fun and Games", @@ -250,7 +251,7 @@ public struct ValueStructure : ValueType // Generates CS0527. 2 つの `Book` コンストラクターは、共通パラメーターを 3 つ共有しています。 *タイトル*および*出版社*の 2 つは、`Publication` コンストラクターのパラメーターに対応します。 3 つ目は*著者*で、プライベートの `authorName` フィールドに格納されています。 1 つのコンストラクターには *isbn* パラメーターが 1 つ含まれていて、`ISBN` 自動プロパティに格納されています。 - 最初のコンストラクターは[この](../language-reference/keywords/this.md)キーワードを使用して、他のコンストラクターを呼び出します。 これがコンストラクターを定義する上で一般的なパターンです。 パラメーターが最も多いコンストラクターを呼び出すときに、パラメーターのより少ないコンストラクターが既定値を提供するものです。 + 最初のコンストラクターは[この](../language-reference/keywords/this.md)キーワードを使用して、他のコンストラクターを呼び出します。 コンストラクター チェーンは、コンストラクターを定義する上で一般的なパターンです。 パラメーターが最も多いコンストラクターを呼び出すときに、パラメーターのより少ないコンストラクターが既定値を提供するものです。 2 番目のコンストラクターは [base](../language-reference/keywords/base.md) キーワードを使用して、基底クラスのコンストラクターにタイトルと出版社名を渡します。 ソース コードで基底クラスのコンストラクターを明示的に呼び出さない場合、C# コンパイラは、基底クラスの既定またはパラメーターなしのコンストラクターへの呼び出しを自動的に提供します。 @@ -260,11 +261,11 @@ public struct ValueStructure : ValueType // Generates CS0527. - 価格に関する、2 つの読み取り専用の `Price` と `Currency` のプロパティ。 これらの値は、`SetPrice` メソッド呼び出しで引数として提供されます。 価格は `bookPrice` というプライベート フィールドに格納されます。 `Currency` プロパティは 3 桁の ISO 通貨記号 (たとえば米ドルの場合は USD) で、プライベートの `ISOCurrencySymbol` フィールドに格納されています。 ISO 通貨記号は プロパティから取得できます。 -- `SetPrice` メソッド。`bookPrice` フィールドおよび `ISOCurrencySymbol` フィールドの値を設定します。 これらは、`Price` プロパティおよび `Currency` プロパティによって返される値です。 +- `SetPrice` メソッド。`bookPrice` フィールドおよび `ISOCurrencySymbol` フィールドの値を設定します。 これらの値は、`Price` プロパティおよび `Currency` プロパティによって返されます。 - `ToString` メソッド (`Publication` から継承) へのオーバーライドと、 メソッドおよび メソッド ( から継承) へのオーバーライド。 - オーバーライドされない限り、 メソッドは参照の等価性を調べます。 つまり、2 つのオブジェクト変数は同じオブジェクトを参照している場合に等価であると見なされます。 一方、`Book` クラスの場合、2 つの `Book` オブジェクトは同じ ISBN を持つ場合に等価であるはずです。 + オーバーライドされない限り、 メソッドは参照の等価性を調べます。 つまり、2 つのオブジェクト変数は同じオブジェクトを参照している場合に等価であると見なされます。 一方、`Book` クラスでは、2 つの `Book` オブジェクトは同じ ISBN を持つ場合に等価であるはずです。 メソッドをオーバーライドする場合、 メソッドもオーバーライドする必要があります。このメソッドは、ランタイムで項目をハッシュされたコレクションに格納し効率的に取得するために使用する値を返すものです。 ハッシュ コードは、等価性のテストと一致する値を返します。 をオーバーライドして、2 つの `Book` オブジェクトの ISBN プロパティが等しい場合に `true` を返すようにしたので、`ISBN` プロパティによって返される文字列の メソッドを呼び出すことにより計算されるハッシュ コードを返します。 @@ -279,11 +280,11 @@ public struct ValueStructure : ValueType // Generates CS0527. ## 抽象基底クラスとその派生クラスの設計 -前述の例では、多くのメソッドの実装を提供する基底クラスを定義し、派生クラスがコードを共有できるようにしました。 しかし多くの場合、基底クラスが実装を提供する必要はありません。 むしろ基底クラスは*抽象クラス*であり、各派生クラスで実装する必要があるメンバーを定義するテンプレートとして機能します。 通常、抽象基底クラスの場合、派生型の実装はそれぞれその型に固有のものです。 +前述の例では、多くのメソッドの実装を提供する基底クラスを定義し、派生クラスがコードを共有できるようにしました。 しかし多くの場合、基底クラスが実装を提供する必要はありません。 むしろ基底クラスは、*抽象メソッド* を宣言する*抽象クラス* であり、各派生クラスで実装する必要があるメンバーを定義するテンプレートとして機能します。 通常、抽象基底クラスでは、派生型の実装はそれぞれその型に固有のものです。 クラスでは出版物に共通の機能の実装が提供されましたが、`Publication` オブジェクトをインスタンス化しても意味はないので、クラスは abstract キーワードでマークしました。 -たとえば、2 次元の閉じた幾何学図形には、2 つのプロパティが含まれます。図形の内部の大きさである面積と、図形の辺に沿った長さである周です。 一方で、これらのプロパティの計算方法は、それぞれの図形によって違います。 たとえば円周の計算式は、三角形の周の計算式とは全く異なります。 +たとえば、2 次元の閉じた幾何学図形には、2 つのプロパティが含まれます。図形の内部の大きさである面積と、図形の辺に沿った長さである周です。 一方で、これらのプロパティの計算方法は、それぞれの図形によって違います。 たとえば、円周の計算式は、三角形の周の計算式とは異なります。 `Shape` クラスは、`abstract` メソッドがある `abstract` クラスです。 これは、派生クラスで同じ機能が共有されるものの、それらの派生クラスではその機能が異なる方法で実装されることを示します。 -次の例では、`Area` と `Perimeter` という 2 つのプロパティを定義する、`Shape` という名前の抽象基底クラスを定義します。 クラスを [abstract](../language-reference/keywords/abstract.md) キーワードでマークするだけでなく、インスタンス メンバーもそれぞれ [abstract](../language-reference/keywords/abstract.md) キーワードでマークしていることに注意してください。 ここで `Shape` は メソッドもオーバーライドして、完全修飾名ではなく、その型の名前を返します。 そして `GetArea` と `GetPerimeter` の 2 つの静的メンバーを定義し、呼び出し元で任意の派生クラスのインスタンスの面積と周を簡単に取得できるようにします。 これらのメソッドのいずれかに派生クラスのインスタンスを渡すとき、ランタイムは派生クラスのメソッド オーバーライドを呼び出します。 +次の例では、`Area` と `Perimeter` という 2 つのプロパティを定義する、`Shape` という名前の抽象基底クラスを定義します。 クラスを [abstract](../language-reference/keywords/abstract.md) キーワードでマークするだけでなく、インスタンス メンバーもそれぞれ [abstract](../language-reference/keywords/abstract.md) キーワードでマークされます。 ここで `Shape` は メソッドもオーバーライドして、完全修飾名ではなく、その型の名前を返します。 そして `GetArea` と `GetPerimeter` の 2 つの静的メンバーを定義し、呼び出し元で任意の派生クラスのインスタンスの面積と周を簡単に取得できるようにします。 これらのメソッドのいずれかに派生クラスのインスタンスを渡すとき、ランタイムは派生クラスのメソッド オーバーライドを呼び出します。 [!code-csharp[Inheritance](../../../samples/snippets/csharp/tutorials/inheritance/shape.cs#1)] @@ -291,7 +292,7 @@ public struct ValueStructure : ValueType // Generates CS0527. [!code-csharp[Inheritance](../../../samples/snippets/csharp/tutorials/inheritance/shape.cs#2)] -次の例では、`Shape` から派生したオブジェクトを使用しています。 ここでは `Shape` から派生したオブジェクトの配列をインスタンス化して、`Shape` クラスの静的メソッドを呼び出します。これにより、返された `Shape` のプロパティ値がラップされます。 ここで、ランタイムが派生型のオーバーライドされたプロパティから値を取得していることに注意してください。 この例ではまた、配列内の `Shape` オブジェクトをそれぞれの派生型にキャストし、キャストが成功すると、その特定の `Shape` サブクラスのプロパティを取得します。 +次の例では、`Shape` から派生したオブジェクトを使用しています。 ここでは `Shape` から派生したオブジェクトの配列をインスタンス化して、`Shape` クラスの静的メソッドを呼び出します。これにより、返された `Shape` のプロパティ値がラップされます。 ランタイムは、派生型のオーバーライドされたプロパティから値を取得します。 この例ではまた、配列内の `Shape` オブジェクトをそれぞれの派生型にキャストし、キャストが成功すると、その特定の `Shape` サブクラスのプロパティを取得します。 [!code-csharp[Inheritance](../../../samples/snippets/csharp/tutorials/inheritance/shape.cs#3)] diff --git a/docs/framework/install/dotnet-35-windows-10.md b/docs/framework/install/dotnet-35-windows-10.md index e6969481059..63b30a94b1d 100644 --- a/docs/framework/install/dotnet-35-windows-10.md +++ b/docs/framework/install/dotnet-35-windows-10.md @@ -1,15 +1,15 @@ --- -title: Windows 8、Windows 8.1、および Windows 10 への .NET Framework 3.5 のインストール -description: Windows 10、Windows 8.1、および Windows 8 に .NET Framework 3.5 をインストールする方法について説明します -author: rlander -ms.author: mairaw -ms.date: 03/30/2018 -ms.openlocfilehash: 226449b8ee7c9360e6bfdc5bfa5dfeb59f19bd2b -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33387417" +title: Windows 8、Windows 8.1、および Windows 10 への .NET Framework 3.5 のインストール +description: Windows 10、Windows 8.1、および Windows 8 に .NET Framework 3.5 をインストールする方法について説明します +author: rlander +ms.author: mairaw +ms.date: 07/16/2018 +ms.openlocfilehash: 7b3b7ca5709008260ea284602a3ed8d2b288c410 +ms.sourcegitcommit: 70c76a12449439bac0f7a359866be5a0311ce960 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/25/2018 +ms.locfileid: "39245540" --- # Windows 8、Windows 8.1、および Windows 10 への .NET Framework 3.5 のインストール @@ -42,3 +42,6 @@ Windows のコントロール パネルを使用して .NET Framework 3.5 を有 インストール中にエラー 0x800f0906、0x800f0907、0x800f081f、0x800F0922 が発生することがあります。その場合は、「[.NET Framework 3.5 インストール エラー: 0x800f0906、0x800f0907、または 0x800f081f](https://support.microsoft.com/help/2734782/net-framework-3-5-installation-error-0x800f0906--0x800f081f--0x800f09)」を参照し、問題の解決方法をご確認ください。 インストールの問題をまだ解決できない場合、またはインターネット接続がない場合は、Windows のインストール メディアを使ってインストールしてみることができます。 詳細については、「[Deploy .NET Framework 3.5 by using Deployment Image Servicing and Management (DISM)](/windows-hardware/manufacture/desktop/deploy-net-framework-35-by-using-deployment-image-servicing-and-management--dism)」 (展開イメージのサービスと管理 (DISM) を利用して .NET Framework 3.5 を展開する) を参照してください。 インストール メディアがない場合は、「[Windows 用のインストール メディアを作成する](https://support.microsoft.com/help/15088/windows-create-installation-media)」を参照してください。 + +> [!WARNING] +> .NET Framework 3.5 のインストールのソースとして Windows Update に依存していない場合は、同じ対応する Windows オペレーティング システムのバージョンからのソースを厳密に使用していることを確認する必要があります。 同じバージョンの Windows に対応しないソース パスを使用しても、一致しないバージョンの .NET Framework 3.5 のインストールは中止されません。 ただし、これによりシステムはサポートされていない使用不能の状態になります。 diff --git a/docs/machine-learning/tutorials/iris-clustering.md b/docs/machine-learning/tutorials/iris-clustering.md new file mode 100644 index 00000000000..220fb833064 --- /dev/null +++ b/docs/machine-learning/tutorials/iris-clustering.md @@ -0,0 +1,218 @@ +--- +title: ML.NET を使用してアヤメの花をクラスター化する (クラスタリング) +description: クラスタリングのシナリオで ML.NET を使用する方法について説明します +author: pkulikov +ms.author: johalex +ms.date: 07/02/2018 +ms.topic: tutorial +ms.custom: mvc +ms.openlocfilehash: 46db9dc7ff425c483f1a9f61da5e806e598b16d5 +ms.sourcegitcommit: 60645077dc4b62178403145f8ef691b13ffec28e +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/10/2018 +ms.locfileid: "37937167" +--- +# チュートリアル: ML.NET を使用してアヤメの花をクラスター化する (クラスタリング) + +> [!NOTE] +> このトピックは現在プレビュー中の ML.NET について述べており、内容が変更される場合があります。 詳しくは、[ML.NET の概要](https://www.microsoft.com/net/learn/apps/machine-learning-and-ai/ml-dotnet)に関するページをご覧ください。 + +このチュートリアルでは、ML.NET を使って[あやめのデータ セット](https://en.wikipedia.org/wiki/Iris_flower_data_set)の[クラスタリング モデル](../resources/tasks.md#clustering)を作成する方法を示します。 + +このチュートリアルでは、次の作業を行う方法について説明します。 +> [!div class="checklist"] +> - 問題を把握する +> - 適切な機械学習タスクを選択する +> - データを準備する +> - データを読み込んで変換する +> - 学習アルゴリズムを選択する +> - モデルをトレーニングする +> - モデルを使用して予測を行う + +## 必須コンポーネント + +- [Visual Studio 2017 15.6 以降](https://visualstudio.microsoft.com/downloads/?utm_medium=microsoft&utm_source=docs.microsoft.com&utm_campaign=button+cta&utm_content=download+vs2017)が ".NET Core クロスプラット フォーム開発" とともにインストールされていること。 + +## 問題を把握する + +この問題は、アヤメの花のセットを特徴に基づいて異なるグループに分類するというものです。 対象となる特徴は、がくの長さと幅および花弁の長さと幅です。 このチュートリアルでは、各花の種類は不明であるものとします。 特徴からデータ セットの構造を理解し、データのインスタンスがこの構造にどのように当てはまるかを予測します。 + +## 適切な機械学習タスクを選択する + +各花がどのグループに属するかわからないので、[教師なし機械学習](../resources/glossary.md#unsupervised-machine-learning)タスクを選択します。 同じグループ内の要素同士の方が他のグループの要素より似ているようにデータ セットをグループに分割するので、[クラスタリング](../resources/tasks.md#clustering)機械学習タスクを使用します。 + +## コンソール アプリケーションを作成する + +1. Visual Studio 2017 を開きます。 **[ファイル]** > **[新規作成]** > **[プロジェクト]** をメニュー バーから選択します。 **[新しいプロジェクト]** ダイアログで、**[Visual C#]** ノードを選択し、**[.NET Core]** ノードを選択します。 次に、**[コンソール アプリ (.NET Core)]** プロジェクト テンプレートを選択します。 **[名前]** テキスト ボックスに「IrisClustering」と入力し、**[OK]** ボタンを選びます。 + +1. プロジェクトに *Data* という名前のディレクトリを作成して、データ セットとモデルのファイルを保存します。 + + **ソリューション エクスプローラー**で、プロジェクトを右クリックし、**[追加]** > **[新しいフォルダー]** を選択します。 「Data」と入力して Enter キーを押します。 + +1. **Microsoft.ML** NuGet パッケージをインストールします。 + + **ソリューション エクスプローラー**で、プロジェクトを右クリックし、**[NuGet パッケージの管理]** を選択します。 [パッケージ ソース] として "nuget.org" を選択し、**[参照]** タブを選択して「**Microsoft.ML**」を検索します。一覧からそのパッケージを選択し、**[インストール]** を選択します。 **[変更のプレビュー]** ダイアログの **[OK]** を選択します。表示されているパッケージのライセンス条項に同意する場合は、**[ライセンスの同意]** ダイアログの **[同意する]** を選択します。 + +## データを準備する + +1. [iris.data](https://github.com/dotnet/machinelearning/blob/master/test/data/iris.data) データ セットをダウンロードし、前の手順で作成した *Data* フォルダーに保存します。 あやめのデータ セットについて詳しくは、Wikipedia の「[Iris flower data set](https://en.wikipedia.org/wiki/Iris_flower_data_set)」(あやめのデータ セット) のページと、データ セットのソースである「[Iris Data Set](http://archive.ics.uci.edu/ml/datasets/Iris)」(あやめのデータ セット) のページをご覧ください。 + +1. **ソリューション エクスプローラー**で、*iris.data* ファイルを右クリックして、**[プロパティ]** を選択します。 **[詳細設定]** で、**[出力ディレクトリにコピー]** の値を **[新しい場合はコピーする]** に変更します。 + +*Iris.data* ファイルには、次の値を表す 5 つの列が含まれます。 + +- がくの長さ (センチメートル単位) +- がくの幅 (センチメートル単位) +- 花弁の長さ (センチメートル単位) +- 花弁の幅 (センチメートル単位) +- アヤメの種類 + +クラスタリングの例が目的なので、このチュートリアルでは最後の列を無視します。 + +## データ クラスを作成する + +入力データと予測のためのクラスを作成します。 + +1. **ソリューション エクスプローラー**で、プロジェクトを右クリックし、**[追加]** > **[新しい項目]** を選択します。 +1. **[新しい項目の追加]** ダイアログ ボックスで、**[クラス]** を選択し、**[名前]** フィールドを「*IrisData.cs*」に変更します。 次に、**[追加]** を選択します。 +1. 以下の `using` ディレクティブを新しいファイルに追加します。 + + [!code-csharp[Add necessary usings](../../../samples/machine-learning/tutorials/IrisClustering/IrisData.cs#1)] + +既存のクラス定義を削除し、`IrisData` クラスと `ClusterPrediction` クラスを定義する次のコードを *IrisData.cs* ファイルに追加します。 + +[!code-csharp[Define data classes](../../../samples/machine-learning/tutorials/IrisClustering/IrisData.cs#2)] + +`IrisData` は入力データ クラスであり、データ セットの各特徴の定義が含まれます。 [Column](xref:Microsoft.ML.Runtime.Api.ColumnAttribute) 属性を使用して、データ セット ファイル内のソース列のインデックスを指定します。 + +`ClusterPrediction` クラスは、`IrisData` インスタンスに適用されたクラスタリング モデルの出力を表します。 [ColumnName](xref:Microsoft.ML.Runtime.Api.ColumnNameAttribute) 属性を使って、`PredictedClusterId` フィールドを **PredictedLabel** 列に、`Distances` フィールドを **Score** 列に、それぞれバインドします。 クラスタリング タスクの場合、これらの列には次の意味があります。 + +- **PredictedLabel** 列には、予測されたクラスターの ID が含まれます。 +- **Score** 列には、クラスターの重心へのユークリッド距離を二乗した値の配列が含まれます。 配列の長さは、クラスターの数と同じです。 + +> [!NOTE] +> 入力データと予測データのクラス内の浮動小数点値を表すには、`float` 型を使います。 + +## データおよびモデルのパスを定義する + +*Program.cs* ファイルに戻り、データ セット ファイルと、モデルを保存するファイルへのパスを保持するために、2 つのフィールドを追加します。 + +- `_dataPath` には、モデルのトレーニングに使用するデータ セットがあるファイルへのパスが含まれます。 +- `_modelPath` には、トレーニング済みモデルが格納されるファイルへのパスが含まれます。 + +`Main` メソッドのすぐ上に次のコードを追加して、それらのパスを指定します。 + +[!code-csharp[Initialize paths](../../../samples/machine-learning/tutorials/IrisClustering/Program.cs#1)] + +上記のコードをコンパイルするには、*Program.cs* ファイルの先頭に次の `using` ディレクティブを追加します。 + +[!code-csharp[Add usings for paths](../../../samples/machine-learning/tutorials/IrisClustering/Program.cs#2)] + +## 学習パイプラインを作成する + +以下の追加の `using` ディレクティブを、*Program.cs* ファイルの先頭に追加します。 + +[!code-csharp[Add Microsoft.ML usings](../../../samples/machine-learning/tutorials/IrisClustering/Program.cs#3)] + +`Main` メソッドで、`Console.WriteLine("Hello World!")` を次のコードに置き換えます。 + +[!code-csharp[Call the Train method](../../../samples/machine-learning/tutorials/IrisClustering/Program.cs#4)] + +`Train` メソッドは、モデルをトレーニングします。 `Main` メソッドのすぐ下に、次のコードを使ってそのメソッドを作成します。 + +```csharp +private static PredictionModel Train() +{ + +} +``` + +学習パイプラインは、モデルのトレーニングに必要なすべてのデータとアルゴリズムを読み込みます。 `Train` メソッドに次のコードを追加します。 + +[!code-csharp[Initialize pipeline](../../../samples/machine-learning/tutorials/IrisClustering/Program.cs#5)] + +## データを読み込んで変換する + +実行する最初のステップでは、トレーニング データ セットを読み込みます。 ここでは、トレーニング データ セットは、`_dataPath` フィールドによってパスが定義されるテキスト ファイルに格納されます。 ファイル内の列はコンマ (",") で区切られます。 `Train` メソッドに次のコードを追加します。 + +[!code-csharp[Add step to load data](../../../samples/machine-learning/tutorials/IrisClustering/Program.cs#6)] + +次のステップでは、 変換クラスを使用して、すべての特徴列を **Features** 列に結合します。 既定では、学習アルゴリズムは **Features** 列の特徴のみを処理します。 次のコードを追加します。 + +[!code-csharp[Add step to concatenate columns](../../../samples/machine-learning/tutorials/IrisClustering/Program.cs#7)] + +## 学習アルゴリズムを選択する + +データをパイプラインに追加して正しい入力形式に変換したら、学習アルゴリズム (**ラーナー**) を選択します。 ラーナーはモデルをトレーニングします。 ML.NET が提供する ラーナーでは、初期クラスターの重心を選択するメソッドが改良された [k 平均法アルゴリズム](https://en.wikipedia.org/wiki/K-means_clustering)が実装されています。 + +前の手順で追加したデータ処理コードの後にある `Train` メソッドに次のコードを追加します。 + +[!code-csharp[Add a learner step](../../../samples/machine-learning/tutorials/IrisClustering/Program.cs#8)] + + プロパティを使ってクラスターの数を指定します。 上記のコードでは、データ セットを 3 つのクラスターに分割することが指定されています。 + +## モデルをトレーニングする + +前のセクションで追加した手順では、トレーニング用にパイプラインを準備しましたが、トレーニングは実行されていません。 `pipeline.Train` メソッドは、`TInput` 型のインスタンスを取り込んで `TOutput` 型のインスタンスを出力するモデルを生成します。 `Train` メソッドに次のコードを追加します。 + +[!code-csharp[Train the model and return](../../../samples/machine-learning/tutorials/IrisClustering/Program.cs#9)] + +### モデルを保存する + +この時点で、既存または新規のどの .NET アプリケーションにも統合できるモデルができました。 モデルを .zip ファイルに保存するには、`Main` メソッドで `Train` メソッドを呼び出している場所の下に、次のコードを追加します。 + +[!code-csharp[Save the model](../../../samples/machine-learning/tutorials/IrisClustering/Program.cs#10)] + +`Main` メソッドで `await` を使用する場合は、`Main` メソッドに `async` 修飾子が必要です。このメソッドは `Task` を返す必要があります。 + +[!code-csharp[Make the Main method async](../../../samples/machine-learning/tutorials/IrisClustering/Program.cs#11)] + +また、*Program.cs* ファイルの先頭に次の `using` ディレクティブを追加する必要もあります。 + +[!code-csharp[Add System.Threading.Tasks using](../../../samples/machine-learning/tutorials/IrisClustering/Program.cs#12)] + +`async Main` メソッドは C# 7.1 に追加された機能であり、プロジェクトの既定の言語バージョンは C# 7.0 であるため、言語バージョンを C# 7.1 以降に変更する必要があります。 そのためには、**ソリューション エクスプローラー**でプロジェクト ノードを右クリックして、**[プロパティ]** を選択します。 **[ビルド]** タブを選択し、**[詳細設定]** ボタンを選択します。 ドロップダウンで **[C# 7.1]** (またはそれ以降のバージョン) を選択します。 **[OK]** ボタンを選択します。 + +## モデルを使用して予測を行う + +テスト データのインスタンスを格納するための `TestIrisData` クラスを作成します。 + +1. **ソリューション エクスプローラー**で、プロジェクトを右クリックし、**[追加]** > **[新しい項目]** を選択します。 +1. **[新しい項目の追加]** ダイアログ ボックスで、**[クラス]** を選択し、**[名前]** フィールドを「*TestIrisData.cs*」に変更します。 次に、**[追加]** を選択します。 +1. 次の例に示すように、静的になるようにクラスを変更します。 + + [!code-csharp[Make class static](../../../samples/machine-learning/tutorials/IrisClustering/TestIrisData.cs#1)] + +このチュートリアルでは、このクラスで 1 つのあやめのデータ インスタンスを示します。 他のシナリオを追加してモデルで実験できます。 `TestIrisData` クラスに次のコードを追加します。 + +[!code-csharp[Test data](../../../samples/machine-learning/tutorials/IrisClustering/TestIrisData.cs#2)] + +指定した項目が属するクラスターを発見するには、*Program.cs* ファイルに戻り、次のコードを `Main` メソッドに追加します。 + +[!code-csharp[Predict and output results](../../../samples/machine-learning/tutorials/IrisClustering/Program.cs#13)] + +プログラムを実行し、指定したデータ インスタンスが含まれるクラスターと、そのインスタンスからクラスターの重心までの平方距離を確認します。 結果は以下のようになるはずです。 パイプラインの処理により、警告または処理メッセージが表示される場合があります。 わかりやすくするために、それらは次の出力から削除してあります。 + +```text +Cluster: 2 +Distances: 0.4192338 0.0008847713 0.9660053 +``` + +おめでとうございます! これで、アヤメのクラスタリングの機械学習モデルを作成し、それを使用して予測を行うことができました。 このチュートリアルのソース コードは、[dotnet/samples](https://github.com/dotnet/samples/tree/master/machine-learning/tutorials/IrisClustering) GitHub リポジトリで確認できます。 + +## 次の手順 + +このチュートリアルでは、次の作業を行う方法を学びました。 +> [!div class="checklist"] +> - 問題を把握する +> - 適切な機械学習タスクを選択する +> - データを準備する +> - データを読み込んで変換する +> - 学習アルゴリズムを選択する +> - モデルをトレーニングする +> - モデルを使用して予測を行う + +学習を続けてその他のサンプルを確認するには、GitHub リポジトリをご覧ください。 +> [!div class="nextstepaction"] +> [dotnet/machinelearning GitHub リポジトリ](https://github.com/dotnet/machinelearning/) diff --git a/docs/machine-learning/tutorials/taxi-fare.md b/docs/machine-learning/tutorials/taxi-fare.md index ed1499e3411..6af53487dc4 100644 --- a/docs/machine-learning/tutorials/taxi-fare.md +++ b/docs/machine-learning/tutorials/taxi-fare.md @@ -6,12 +6,12 @@ ms.author: johalex ms.date: 06/18/2018 ms.topic: tutorial ms.custom: mvc -ms.openlocfilehash: 9706dad0a8e32651496e0404be4501c2c70e9d75 -ms.sourcegitcommit: ed7b4b9b77d35e94a35a2634e8c874f46603fb2b +ms.openlocfilehash: e3ff2124a43cf42ce26cf94cfd5384387eef0ed9 +ms.sourcegitcommit: 60645077dc4b62178403145f8ef691b13ffec28e ms.translationtype: HT ms.contentlocale: ja-JP -ms.lasthandoff: 06/26/2018 -ms.locfileid: "36948632" +ms.lasthandoff: 07/10/2018 +ms.locfileid: "37937073" --- # チュートリアル: ML.NET を使用してニューヨークのタクシー運賃を予測する (回帰) @@ -296,6 +296,6 @@ private static void Evaluate(PredictionModel m > * モデルを評価する > * モデルを使用して予測を行う -学習を続けてその他のサンプルを確認するには、GitHub リポジトリをご覧ください。 +さらに詳しく学習するには、次のチュートリアルに進んでください。 > [!div class="nextstepaction"] -> [dotnet/machinelearning GitHub リポジトリ](https://github.com/dotnet/machinelearning/) +> [アヤメのクラスタリング](iris-clustering.md) diff --git a/docs/standard/asynchronous-programming-patterns/deciding-when-to-implement-the-event-based-asynchronous-pattern.md b/docs/standard/asynchronous-programming-patterns/deciding-when-to-implement-the-event-based-asynchronous-pattern.md index fdc31e98b65..65b9b65a78f 100644 --- a/docs/standard/asynchronous-programming-patterns/deciding-when-to-implement-the-event-based-asynchronous-pattern.md +++ b/docs/standard/asynchronous-programming-patterns/deciding-when-to-implement-the-event-based-asynchronous-pattern.md @@ -1,27 +1,28 @@ --- -title: イベントベースの非同期パターンをいつ実装するかの決定 -ms.date: 03/30/2017 -ms.technology: dotnet-standard -helpviewer_keywords: -- Event-based Asynchronous Pattern -- ProgressChangedEventArgs class -- BackgroundWorker component -- events [.NET Framework], asynchronous -- AsyncOperationManager class -- threading [.NET Framework], asynchronous features -- AsyncOperation class -- AsyncCompletedEventArgs class -ms.assetid: a00046aa-785d-4f7f-a8e5-d06475ea50da -ms.openlocfilehash: 3f9b18b3362155e256c922a84f3f1cdb6d255a4b -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 +title: イベントベースの非同期パターンをいつ実装するかの決定 +ms.date: 03/30/2017 +ms.technology: dotnet-standard +helpviewer_keywords: +- Event-based Asynchronous Pattern +- ProgressChangedEventArgs class +- BackgroundWorker component +- events [.NET Framework], asynchronous +- AsyncOperationManager class +- threading [.NET Framework], asynchronous features +- AsyncOperation class +- AsyncCompletedEventArgs class +ms.assetid: a00046aa-785d-4f7f-a8e5-d06475ea50da +ms.openlocfilehash: b00b01cb82f7fa2f1d9af42438c37592bb1e8181 +ms.sourcegitcommit: 2d8b7488d94101b534ca3e9780b1c1e840233405 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/23/2018 +ms.locfileid: "39198878" --- # イベントベースの非同期パターンをいつ実装するかの決定 イベント ベースの非同期パターンは、クラスの非同期動作を公開します。 このパターンを導入すると、[!INCLUDE[dnprdnshort](../../../includes/dnprdnshort-md.md)] では、非同期動作を公開する 2 つのパターンが定義されます。 インターフェイスに基づく非同期パターンとイベント ベースのパターンです。 このトピックでは、両方のパターンをどのような状況で実装するべきか説明します。 - インターフェイスによる非同期プログラミングの詳細については、「[イベント ベースの非同期パターン (EAP)](../../../docs/standard/asynchronous-programming-patterns/event-based-asynchronous-pattern-eap.md)」を参照してください。 + インターフェイスによる非同期プログラミングについて詳しくは、「[非同期プログラミング モデル (APM)](../../../docs/standard/asynchronous-programming-patterns/asynchronous-programming-model-apm.md)」をご覧ください。 ## 一般原則 一般的に、可能であれば、イベント ベースの非同期パターンを利用して非同期機能を公開してください。 ただし、イベント ベースのパターンでは満たせない要件もあります。 そのようなとき、場合によっては、イベント ベースのパターンに加え、 パターンも実装する必要があります。 diff --git a/docs/standard/asynchronous-programming-patterns/how-to-use-components-that-support-the-event-based-asynchronous-pattern.md b/docs/standard/asynchronous-programming-patterns/how-to-use-components-that-support-the-event-based-asynchronous-pattern.md index 312b4924981..33449b1962b 100644 --- a/docs/standard/asynchronous-programming-patterns/how-to-use-components-that-support-the-event-based-asynchronous-pattern.md +++ b/docs/standard/asynchronous-programming-patterns/how-to-use-components-that-support-the-event-based-asynchronous-pattern.md @@ -1,29 +1,29 @@ --- -title: '方法 : イベントベースの非同期パターンをサポートするコンポーネントを使用する' -ms.date: 03/30/2017 -ms.technology: dotnet-standard -dev_langs: -- csharp -- vb -helpviewer_keywords: -- Event-based Asynchronous Pattern -- ProgressChangedEventArgs class -- BackgroundWorker component -- events [.NET Framework], asynchronous -- Asynchronous Pattern -- AsyncOperationManager class -- threading [.NET Framework], asynchronous features -- components [.NET Framework], asynchronous -- AsyncOperation class -- threading [Windows Forms], asynchronous features -- AsyncCompletedEventArgs class -ms.assetid: 35e9549c-1568-4768-ad07-17cc6dff11e1 -ms.openlocfilehash: f0bf9b1da76033ef40cc72657ee722083a6f8b1a -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33567634" +title: '方法 : イベントベースの非同期パターンをサポートするコンポーネントを使用する' +ms.date: 03/30/2017 +ms.technology: dotnet-standard +dev_langs: +- csharp +- vb +helpviewer_keywords: +- Event-based Asynchronous Pattern +- ProgressChangedEventArgs class +- BackgroundWorker component +- events [.NET Framework], asynchronous +- Asynchronous Pattern +- AsyncOperationManager class +- threading [.NET Framework], asynchronous features +- components [.NET Framework], asynchronous +- AsyncOperation class +- threading [Windows Forms], asynchronous features +- AsyncCompletedEventArgs class +ms.assetid: 35e9549c-1568-4768-ad07-17cc6dff11e1 +ms.openlocfilehash: a96641e6dd42e033f2d28b847fc071dfc514912d +ms.sourcegitcommit: 60645077dc4b62178403145f8ef691b13ffec28e +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/10/2018 +ms.locfileid: "37936998" --- # 方法 : イベントベースの非同期パターンをサポートするコンポーネントを使用する 多くのコンポーネントでは、非同期的に作業を実行するオプションが提供されます。 たとえば、 コンポーネントでは、メイン スレッドが中断されることなく、実行され続ける間に、"バックグラウンドで" 音声とイメージを読み込むことができます。 @@ -63,4 +63,4 @@ ms.locfileid: "33567634" ## 参照 [方法: バックグラウンドで操作を実行する](../../../docs/framework/winforms/controls/how-to-run-an-operation-in-the-background.md) [イベントベースの非同期パターンの概要](../../../docs/standard/asynchronous-programming-patterns/event-based-asynchronous-pattern-overview.md) - [ビルド内にありません: Visual Basic でのマルチスレッド](https://msdn.microsoft.com/library/c731a50c-09c1-4468-9646-54c86b75d269) + [Visual Basic でのマルチスレッド](../../../docs/visual-basic/programming-guide/concepts/threading/multithreaded-applications.md) diff --git a/docs/standard/guidance-architecture.md b/docs/standard/guidance-architecture.md index cd20361f14b..d2b097837fc 100644 --- a/docs/standard/guidance-architecture.md +++ b/docs/standard/guidance-architecture.md @@ -1,16 +1,16 @@ --- -title: .NET アーキテクチャ ガイダンス -description: .NET ソフトウェアを設計し、構築するときの推奨プラクティスを紹介します。 -author: BillWagner -ms.author: wiwagn -ms.date: 10/26/2017 -ms.technology: dotnet -ms.openlocfilehash: 7d636e842c7ec91949f2557f74ae724def858053 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33570500" +title: .NET アーキテクチャ ガイダンス +description: .NET ソフトウェアを設計し、構築するときの推奨プラクティスを紹介します。 +author: BillWagner +ms.author: wiwagn +ms.date: 10/26/2017 +ms.technology: dotnet +ms.openlocfilehash: e63f7043b2dfdbe367ed2cbfba13bc6985c1ead6 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404175" --- # .NET アーキテクチャ ガイダンス @@ -28,4 +28,8 @@ ms.locfileid: "33570500" ## [コンテナーとマイクロサービス ベースのアプリケーションの設計](microservices-architecture/index.md) -このガイドでは、マイクロサービス ベースのアプリケーションの開発とコンテナーを使用してこれらを管理する方法を紹介します。 .NET Core と Docker のコンテナーを使用したアーキテクチャの設計と実装アプローチについて説明します。 +このガイドでは、マイクロサービス ベースのアプリケーションの開発とコンテナーを使用してこれらを管理する方法を紹介します。 .NET Core と Docker のコンテナーを使用したアーキテクチャの設計と実装アプローチについて説明します。 + +## [サーバーレス アプリ: アーキテクチャ、パターン、および Azure の実装](serverless-architecture/index.md) + +これは、Azure を使用した例を使って、サーバーレス アプリケーションを構築するためのガイドです。 さまざまなアーキテクチャと設計アプローチ、サーバーレスに含まれる利点と課題について説明し、サーバーレス アプリのシナリオとユース ケースを提供します。 diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/explore-custom-http-call-retries-exponential-backoff.md b/docs/standard/microservices-architecture/implement-resilient-applications/explore-custom-http-call-retries-exponential-backoff.md new file mode 100644 index 00000000000..951dc229091 --- /dev/null +++ b/docs/standard/microservices-architecture/implement-resilient-applications/explore-custom-http-call-retries-exponential-backoff.md @@ -0,0 +1,122 @@ +--- +title: カスタム HTTP 呼び出しの指数バックオフを含む再試行について +description: 考えられる HTTP 障害シナリオを処理するため、ゼロからカスタム HTTP 呼び出しの指数バックオフを含む再試行を実装する方法について説明します。 +author: CESARDELATORRE +ms.author: wiwagn +ms.date: 06/08/2018 +ms.openlocfilehash: c323b8c4e783ed18c601562cfb25e1ca4986d499 +ms.sourcegitcommit: 59b51cd7c95c75be85bd6ef715e9ef8c85720bac +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/06/2018 +ms.locfileid: "37878749" +--- +# カスタム HTTP 呼び出しの指数バックオフを含む再試行について + +回復力のあるマイクロサービスを作成するには、考えられる HTTP 障害シナリオに対処する必要があります。 これらの障害に対処する 1 つの方法として (ただし推奨されません)、指数バックオフを含む再試行の実装を作成します。 + +**重要な注意事項:** このセクションでは、HTTP 呼び出しの再試行を実装するカスタム コードを作成する方法を示します。 ただし、これをユーザーが独自に行うことは推奨されていませんが、.NET Core 2.1 以降で使用可能なより強力で信頼性が高いながらもよりシンプルなメカニズム (Polly での `HttpClientFactory` など) を使用することが推奨されています。 これらの推奨アプローチについては、以降のセクションで説明します。 + +最初の考察として、[RetryWithExponentialBackoff.cs](https://gist.github.com/CESARDELATORRE/6d7f647b29e55fdc219ee1fd2babb260) にあるような指数バックオフ用のユーティリティ クラスを使用した独自のコードに加えて、次に示すようなコード (この [GitHub リポジトリ](https://gist.github.com/CESARDELATORRE/d80c6423a1aebaffaf387469f5194f5b)でも提供されています) を実装することも可能です。 + +```csharp +public sealed class RetryWithExponentialBackoff +{ + private readonly int maxRetries, delayMilliseconds, maxDelayMilliseconds; + + public RetryWithExponentialBackoff(int maxRetries = 50, + int delayMilliseconds = 200, + int maxDelayMilliseconds = 2000) + { + this.maxRetries = maxRetries; + this.delayMilliseconds = delayMilliseconds; + this.maxDelayMilliseconds = maxDelayMilliseconds; + } + + public async Task RunAsync(Func func) + { + ExponentialBackoff backoff = new ExponentialBackoff(this.maxRetries, + this.delayMilliseconds, + this.maxDelayMilliseconds); + retry: + try + { + await func(); + } + catch (Exception ex) when (ex is TimeoutException || + ex is System.Net.Http.HttpRequestException) + { + Debug.WriteLine("Exception raised is: " + + ex.GetType().ToString() + + " –Message: " + ex.Message + + " -- Inner Message: " + + ex.InnerException.Message); + await backoff.Delay(); + goto retry; + } + } +} + +public struct ExponentialBackoff +{ + private readonly int m_maxRetries, m_delayMilliseconds, m_maxDelayMilliseconds; + private int m_retries, m_pow; + + public ExponentialBackoff(int maxRetries, int delayMilliseconds, + int maxDelayMilliseconds) + { + m_maxRetries = maxRetries; + m_delayMilliseconds = delayMilliseconds; + m_maxDelayMilliseconds = maxDelayMilliseconds; + m_retries = 0; + m_pow = 1; + } + + public Task Delay() + { + if (m_retries == m_maxRetries) + { + throw new TimeoutException("Max retry attempts exceeded."); + } + ++m_retries; + if (m_retries < 31) + { + m_pow = m_pow << 1; // m_pow = Pow(2, m_retries - 1) + } + int delay = Math.Min(m_delayMilliseconds * (m_pow - 1) / 2, + m_maxDelayMilliseconds); + return Task.Delay(delay); + } +} +``` + +クライアント C\# アプリケーション (別の Web API クライアント マイクロサービス、ASP.NET MVC アプリケーション、または C\# Xamarin アプリケーション) でこのコードを使用することは簡単です。 次の例は、HttpClient クラスの使い方を示しています。 + +```csharp +public async Task GetCatalogItems(int page,int take, int? brand, int? type) +{ + _apiClient = new HttpClient(); + var itemsQs = $"items?pageIndex={page}&pageSize={take}"; + var filterQs = ""; + var catalogUrl = $"{_remoteServiceBaseUrl}items{filterQs}?pageIndex={page}&pageSize={take}"; + var dataString = ""; + // + // Using HttpClient with Retry and Exponential Backoff + // + var retry = new RetryWithExponentialBackoff(); + await retry.RunAsync(async () => + { + // work with HttpClient call + dataString = await _apiClient.GetStringAsync(catalogUrl); + }); + return JsonConvert.DeserializeObject(dataString); +} +``` + +このコードは概念の実証用にのみ使用してください。 次のセクションでは、HttpClientFactory を使用して、よりシンプルでありながらより高度なアプローチを使用する方法について説明します。 +HttpClientFactory は、Polly のような回復性が実証されているライブラリを持つ、.NET Core 2.1 以降で使用できます。 + + +>[!div class="step-by-step"] +[前へ](implement-resilient-entity-framework-core-sql-connections.md) +[次へ](use-httpclientfactory-to-implement-resilient-http-requests.md) \ No newline at end of file diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/handle-partial-failure.md b/docs/standard/microservices-architecture/implement-resilient-applications/handle-partial-failure.md index 8cda980b97a..7912471489d 100644 --- a/docs/standard/microservices-architecture/implement-resilient-applications/handle-partial-failure.md +++ b/docs/standard/microservices-architecture/implement-resilient-applications/handle-partial-failure.md @@ -1,15 +1,15 @@ --- -title: 部分的なエラーの処理 -description: コンテナー化された .NET アプリケーションの .NET マイクロサービス アーキテクチャ | 部分的なエラーの処理 -author: CESARDELATORRE -ms.author: wiwagn -ms.date: 05/26/2017 -ms.openlocfilehash: 957a0b1b8b4d217fac591db54e4ee053098bc7da -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37105196" +title: 部分的なエラーの処理 +description: コンテナー化された .NET アプリケーションの .NET マイクロサービス アーキテクチャ | 部分的なエラーの処理 +author: CESARDELATORRE +ms.author: wiwagn +ms.date: 06/08/2018 +ms.openlocfilehash: 723719b22c1c7de63f19f68acf91e6499c1a4e43 +ms.sourcegitcommit: 59b51cd7c95c75be85bd6ef715e9ef8c85720bac +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/06/2018 +ms.locfileid: "37875184" --- # 部分的なエラーの処理 @@ -27,7 +27,7 @@ eShopOnContainers サンプル アプリケーションの [Order details]\(注 **図 10-2** HTTP 要求の長いチェーンが特徴の不適切な設計の影響 -分散型のクラウド ベースのシステムでは、すべての依存関係自体に優れた可用性がある場合でも、事実上、断続的なエラーは必ず発生します。 この点を考慮する必要があります。 +分散型のクラウド ベースのシステムでは、すべての依存関係自体に優れた可用性がある場合でも、断続的なエラーは必ず発生します。 この点を考慮する必要があります。 フォールト トレランスを確保するための手法を設計および実装していない場合は、たとえ短時間のダウンタイムであっても増幅する可能性があります。 たとえば、可用性がそれぞれ 99.99% の依存関係が 50 個ある場合、この波及効果のために毎月数時間のダウンタイムが発生します。 マイクロサービスの依存関係が大量の要求を処理しているときにエラーが発生すると、そのエラーによって各サービスのすべての使用可能な要求スレッドが短時間で飽和状態になり、アプリケーション全体がクラッシュする可能性があります。 @@ -35,7 +35,7 @@ eShopOnContainers サンプル アプリケーションの [Order details]\(注 **図 10-3** 同期 HTTP 呼び出しの長いチェーンがあるマイクロサービスによって増幅される部分的なエラー -この問題を最小限に抑えるために、「*マイクロ サービスの自律性を強制する非同期マイクロ サービスの統合*」(アーキテクチャの章) セクションでは、内部のマイクロサービス全体で非同期通信を使用することをお勧めしました。 次のセクションで簡単に説明します。 +この問題を最小限に抑えるために、「*マイクロ サービスの自律性を強制する非同期マイクロ サービスの統合*」 (アーキテクチャの章) セクションで、内部のマイクロサービス全体で非同期通信を使用することをお勧めしています。 さらに、部分的なエラーを処理する (つまり、回復力のあるマイクロサービスとクライアント アプリケーションを構築する) ようにマイクロサービスとクライアント アプリケーションを設計することが不可欠です。 diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/implement-circuit-breaker-pattern.md b/docs/standard/microservices-architecture/implement-resilient-applications/implement-circuit-breaker-pattern.md index d25a78f73c1..97741bfec08 100644 --- a/docs/standard/microservices-architecture/implement-resilient-applications/implement-circuit-breaker-pattern.md +++ b/docs/standard/microservices-architecture/implement-resilient-applications/implement-circuit-breaker-pattern.md @@ -1,173 +1,103 @@ --- -title: サーキット ブレーカー パターンの実装 -description: '.NET マイクロサービス: コンテナー化された .NET アプリケーションのアーキテクチャ | サーキット ブレーカー パターンの実装' -author: CESARDELATORRE -ms.author: wiwagn -ms.date: 11/12/2017 -ms.openlocfilehash: 2c89992c4c60ca7f1085050e6fed4922ecd4d8cc -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37106131" +title: サーキット ブレーカー パターンの実装 +description: '.NET マイクロサービス: コンテナー化された .NET アプリケーションのアーキテクチャ | HTTP 再試行の補足システムとしてサーキット ブレーカー パターンを実装する' +author: CESARDELATORRE +ms.author: wiwagn +ms.date: 07/03/2018 +ms.openlocfilehash: d5902c5a0744d74ae5086a4df3aee606b24b6030 +ms.sourcegitcommit: 59b51cd7c95c75be85bd6ef715e9ef8c85720bac +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/06/2018 +ms.locfileid: "37875168" --- -# サーキット ブレーカー パターンの実装 +# サーキット ブレーカー パターンを実装する 前述のように、リモート サービスやリソースに接続を試行する際に発生し得る、復旧にどのくらい時間がかかるかわからない障害を処理する必要があります。 この種類の障害を処理することにより、アプリケーションの安定性と回復性が向上します。 -分散環境において、リモート リソースとサービスの呼び出しは、低速なネットワーク接続やタイムアウト、あるいはリソースが低速であったり、一時的に利用不可能であったりなどの、一時的な障害が原因で失敗することがあります。 このような障害は通常しばらくすると自動的に修正されます。堅牢なクラウド アプリケーションなら再試行パターンなどの方法でそうした障害を処理する備えができているはずです。 +分散環境において、リモート リソースとサービスの呼び出しは、低速なネットワーク接続やタイムアウト、あるいはリソースが低速であったり、一時的に利用不可能であったりなどの、一時的な障害が原因で失敗することがあります。 このような障害は通常しばらくすると自動的に修正されます。堅牢なクラウド アプリケーションなら "再試行パターン" などの方法でそうした障害を処理する備えができているはずです。 -ただし、予期しないイベントが原因で、障害の修正に非常に長い時間がかかる状況もあり得ます。 このような障害の重大度は、部分的な接続の損失からサービスの完全な不具合まで多岐にわたります。 このような状況では、アプリケーションが成功の見込みの薄い操作を再試行し続けることは無駄かもしれません。 代わりに、アプリケーションが操作の失敗を受け入れ、失敗を処理するようにコードを書く必要があります。 +ただし、予期しないイベントが原因で、障害の修正に非常に長い時間がかかる状況もあり得ます。 このような障害の重大度は、部分的な接続の損失からサービスの完全な不具合まで多岐にわたります。 このような状況では、アプリケーションが成功の見込みの薄い操作を再試行し続けることは無駄かもしれません。 -サーキット ブレーカー パターンの目的は、再試行パターンとは異なります。 再試行パターンでは、操作が最終的には成功するとの見込みをもってアプリケーションに操作を再試行させます。 サーキット ブレーカー パターンは、失敗する可能性の高い操作をアプリケーションが実行しないようにします。 アプリケーションは、サーキット ブレーカーを介して操作を呼び出す再試行パターンを使用すれば、これら 2 つのパターンを結合できます。 しかし、再試行のロジックはサーキット ブレーカーが返す例外に対応できる必要があり、障害が一時的ではないことをサーキット ブレーカーが示す場合、再試行を中止する必要があります。 +代わりに、アプリケーションが操作の失敗を受け入れ、失敗を処理するようにコードを書く必要があります。 -## Polly によるサーキット ブレーカー パターンの実装 +HTTP 再試行を不注意に使用すると、自分のソフトウェアにサービス拒否 ([DoS](https://en.wikipedia.org/wiki/Denial-of-service_attack)) 攻撃が発生することがあります。 マイクロサービスが失敗したか、動作が遅いとき、複数のクライアントで失敗した要求の再試行が繰り返されることがあります。 その結果、失敗を繰り返すサービスに宛てられるトラフィックが急激に増えるという危険なリスクが発生します。 -再試行の実装と同じように、サーキット ブレーカーの推奨されるアプローチは、Polly など実績のある .NET ライブラリを活用することです。 +そのため、試行を続けるに値しないとき、再試行が要求を停止するように、何らかの防壁が必要になります。 その防壁こそがサーキット ブレーカーです。 -eShopOnContainers アプリケーションは、HTTP 再試行の実装に Polly サーキット ブレーカー ポリシーを使用しています。 実際、このアプリケーションは両方のポリシーを ResilientHttpClient ユーティリティ クラスに適用しています。 HTTP 要求に (eShopOnContainers から) ResilientHttpClient 型のオブジェクトを使用する場合、これら両方のポリシーを適用することになりますが、さらにポリシーを追加することもできます。 +サーキット ブレーカー パターンの目的は、"再試行パターン" とは異なります。 "再試行パターン" では、操作が最終的には成功するとの見込みをもってアプリケーションに操作を再試行させます。 サーキット ブレーカー パターンは、失敗する可能性の高い操作をアプリケーションが実行しないようにします。 アプリケーションでは、これら 2 つのパターンを組み合わせることができます。 しかしながら、再試行のロジックはサーキット ブレーカーが返す例外に対応できる必要があり、障害が一時的ではないことをサーキット ブレーカーが示す場合、再試行を中止する必要があります。 -HTTP 呼び出しの再試行に使用されるコードに追加する必要があるのは、次のコードの最後の部分で示されているように、使用するポリシーのリストにサーキット ブレーカー ポリシーを加えるコードだけです。 +## HttpClientFactory と Polly でサーキット ブレーカー パターンを実装する -```csharp -public ResilientHttpClient CreateResilientHttpClient() - => new ResilientHttpClient(CreatePolicies(), _logger); +再試行の実装と同じように、サーキット ブレーカーの推奨されるアプローチは、Polly など実績のある .NET ライブラリを活用し、HttpClientFactory とネイティブ統合することです。 -private Policy[] CreatePolicies() - => new Policy[] - { - Policy.Handle() - .WaitAndRetryAsync( - // number of retries - 6, - // exponential backofff - retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), - // on retry - (exception, timeSpan, retryCount, context) => - { - var msg = $"Retry {retryCount} implemented with Polly RetryPolicy " + - $"of {context.PolicyKey} " + - $"at {context.ExecutionKey}, " + - $"due to: {exception}."; - _logger.LogWarning(msg); - _logger.LogDebug(msg); - }), - Policy.Handle() - .CircuitBreakerAsync( - // number of exceptions before breaking circuit - 5, - // time circuit opened before retry - TimeSpan.FromMinutes(1), - (exception, duration) => - { - // on circuit opened - _logger.LogTrace("Circuit breaker opened"); - }, - () => - { - // on circuit closed - _logger.LogTrace("Circuit breaker reset"); - }) - }; -} -``` +サーキット ブレーカー ポリシーを HttpClientFactory の外向きミドルウェア パイプラインに追加することは、HttpClientFactory の使用時、既にあるものにコードの増分を 1 つ分追加することと同じくらい簡単です。 -このコードは、ポリシーを HTTP ラッパーに追加します。 このポリシーは、exceptionsAllowedBeforeBreaking パラメーターで渡される指定された回数 (この例では 5 回) の連続する例外をコードが検出するとオープン状態になるサーキット ブレーカーを定義します。 サーキットがオープン状態の場合、HTTP 要求は機能せず、例外が発生します。 +HTTP 呼び出しの再試行に使用されるコードに追加する必要があるのは、ConfigureServices() メソッドから抜粋された次の増分コードで示されているように、使用するポリシーのリストにサーキット ブレーカー ポリシーを追加するコードだけです。 -サーキット ブレーカーは、HTTP 呼び出しを実行しているクライアント アプリケーションまたはサービスとは別の環境に展開されている特定のリソースに問題がある場合に、要求をフォールバック インフラストラクチャにリダイレクトするために使用する必要もあります。 こうすれば、バックエンドのマイクロサービスのみに影響を与え、クライアント アプリケーションには影響を与えないデータセンターの停止が生じた場合に、クライアント アプリケーションはフォールバック サービスにリダイレクトできます。 Polly では、この[フェールオーバー ポリシー](https://github.com/App-vNext/Polly/wiki/Polly-Roadmap#failover-policy) シナリオを自動化するための新しいポリシーが計画されています。 - -もちろん、これらすべての機能は、位置を意識することなく Azure に自動的にフェールオーバーを管理させるのとは対照的に、フェールオーバーを .NET コード内から管理する場合のためのものです。 +```csharp +//ConfigureServices() - Startup.cs +services.AddHttpClient() + .SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Set lifetime to 5 minutes + .AddPolicyHandler(GetRetryPolicy()) + .AddPolicyHandler(GetCircuitBreakerPolicy()); +``` -## eShopOnContainers から ResilientHttpClient ユーティリティ クラスを使用する +`AddPolicyHandler()` メソッドは、使用する HttpClient オブジェクトにポリシーを追加します。 この場合、サーキット ブレーカーの Polly のポリシーを追加しています。 -ResilientHttpClient ユーティリティ クラスは、.NET HttpClient クラスを使用するのと同じような方法で使用します。 eShopOnContainers MVC Web アプリからの次の例では (OrderController に使用される OrderingService エージェント クラス)、ResilientHttpClient オブジェクトはコンストラクターの httpClient パラメーターにより挿入されます。 その後オブジェクトは HTTP 要求を実行するために使用されます。 +手法のモジュール性を高める目的で、次のコードのように、GetCircuitBreakerPolicy() という名前の別個のメソッドにサーキット ブレーカー ポリシーが定義されます。 ```csharp -public class OrderingService : IOrderingService +static IAsyncPolicy GetCircuitBreakerPolicy() { - private IHttpClient _apiClient; - private readonly string _remoteServiceBaseUrl; - private readonly IOptionsSnapshot _settings; - private readonly IHttpContextAccessor _httpContextAccesor; - - public OrderingService(IOptionsSnapshot settings, - IHttpContextAccessor httpContextAccesor, - IHttpClient httpClient) - { - _remoteServiceBaseUrl = $"{settings.Value.OrderingUrl}/api/v1/orders"; - _settings = settings; - _httpContextAccesor = httpContextAccesor; - _apiClient = httpClient; - } - - async public Task> GetMyOrders(ApplicationUser user) - { - var context = _httpContextAccesor.HttpContext; - var token = await context.Authentication.GetTokenAsync("access_token"); - _apiClient.Inst.DefaultRequestHeaders.Authorization = new - System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); - var ordersUrl = _remoteServiceBaseUrl; - var dataString = await _apiClient.GetStringAsync(ordersUrl); - var response = JsonConvert.DeserializeObject>(dataString); - return response; - } - - // Other methods ... - async public Task CreateOrder(Order order) - { - var context = _httpContextAccesor.HttpContext; - var token = await context.Authentication.GetTokenAsync("access_token"); - _apiClient.Inst.DefaultRequestHeaders.Authorization = new - System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); - _apiClient.Inst.DefaultRequestHeaders.Add("x-requestid", - order.RequestId.ToString()); - var ordersUrl = $"{_remoteServiceBaseUrl}/new"; - order.CardTypeId = 1; - order.CardExpirationApiFormat(); - SetFakeIdToProducts(order); - var response = await _apiClient.PostAsync(ordersUrl, order); - response.EnsureSuccessStatusCode(); - } + return HttpPolicyExtensions + .HandleTransientHttpError() + .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)); } ``` -\_apiClient メンバー オブジェクトが使用される場合はいつでも、このオブジェクトは内部的にラッパー クラスを Polly ポリシーと共に使用します。このポリシーには、再試行ポリシー、サーキット ブレーカー ポリシーと、Polly ポリシー コレクションからの適用したい任意の他のポリシーが含まれます。 +上記のコード例では、HTTP 要求の再試行時、例外が 5 つ発生したとき、サーキットを中断する (またはオープン状態にする) ようにサーキット ブレーカー ポリシーが構成されています。 30 秒がその期間 (中断) になります。 -## eShopOnContainers で再試行をテストする +サーキット ブレーカーは、HTTP 呼び出しを実行しているクライアント アプリケーションまたはサービスとは別の環境に展開されている特定のリソースに問題がある場合に、要求をフォールバック インフラストラクチャにリダイレクトするために使用する必要もあります。 こうすれば、バックエンドのマイクロサービスのみに影響を与え、クライアント アプリケーションには影響を与えないデータセンターの停止が生じた場合に、クライアント アプリケーションはフォールバック サービスにリダイレクトできます。 Polly では、この[フェールオーバー ポリシー](https://github.com/App-vNext/Polly/wiki/Polly-Roadmap#failover-policy) シナリオを自動化するための新しいポリシーが計画されています。 -Docker ホスト内で eShopOnContainers ソリューションを起動する場合、このソリューションは複数のコンテナーを起動する必要があります。 SQL Server コンテナーなど、一部のコンテナーは起動と初期化が低速です。 eShopOnContainers アプリケーションを Docker に初めて展開する場合は、イメージとデータベースを設定する必要があるため、特にそうです。 一部のコンテナーは他のコンテナーより起動が低速だという事実により、以前のセクションで説明したように docker-compose レベルでコンテナー間の依存関係を設定している場合であっても、残りのサービスによる初期化時の HTTP 例外のスローが引き起こされる可能性があります。 コンテナー間の docker-compose 依存関係は、プロセス レベルだけのものです。 コンテナーのエントリ ポイント プロセスは起動されても、SQL Server はクエリに対して準備ができていないことがあります。 結果としてエラーの連鎖が生じ、アプリケーションがその特定のコンテナーを利用しようとするときに例外が発生することがあります。 +これらすべての機能は、位置を意識することなく Azure に自動的にフェールオーバーを管理させるのとは対照的に、フェールオーバーを .NET コード内から管理する場合のためのものです。 -また、起動時のこのタイプのエラーは、アプリケーションをクラウドに展開する際に生じることもあります。 その場合、オーケストレーターは、クラスターのノード全体でコンテナーの数を分散させる際に、コンテナーを 1 つのノードまたは VM から別の場所に移動することがあります (つまり、新しいインスタンスを起動する)。 +使用という観点からは、HttpClient を使用するとき、ここで新しいものは何も追加する必要がありません。前のセクションで示したように、HttpClient と HttpClientFactory の使用時とコードが同じであるからです。 -eShopOnContainers は、すでに説明した再試行パターンを使用してこの問題を解決します。 これは、ソリューションを起動した際に次のようなログ トレースや警告が発生する理由でもあります。 +## eShopOnContainers で HTTP の再試行とサーキット ブレーカーをテストする -> "**Retry 1 implemented with Polly's RetryPolicy**, due to: System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.Http.CurlException: Couldn't connect to server\\n at System.Net.Http.CurlHandler.ThrowIfCURLEError(CURLcode error)\\n at \[...\]. -## eShopOnContainers でサーキット ブレーカーをテストする +Docker ホスト内で eShopOnContainers ソリューションを起動する場合、このソリューションは複数のコンテナーを起動する必要があります。 SQL Server コンテナーなど、一部のコンテナーは起動と初期化が低速です。 eShopOnContainers アプリケーションを Docker に初めて展開する場合は、イメージとデータベースを設定する必要があるため、特にそうです。 一部のコンテナーは他のコンテナーより起動が低速だという事実により、以前のセクションで説明したように docker-compose レベルでコンテナー間の依存関係を設定している場合であっても、残りのサービスによる初期化時の HTTP 例外のスローが引き起こされる可能性があります。 コンテナー間の docker-compose 依存関係は、プロセス レベルだけのものです。 コンテナーのエントリ ポイント プロセスは起動されても、SQL Server はクエリに対して準備ができていないことがあります。 結果としてエラーの連鎖が生じ、アプリケーションがその特定のコンテナーを利用しようとするときに例外が発生することがあります。 + +また、起動時のこのタイプのエラーは、アプリケーションをクラウドに展開する際に生じることもあります。 その場合、オーケストレーターは、クラスターのノード全体でコンテナーの数を分散させる際に、コンテナーを 1 つのノードまたは VM から別の場所に移動することがあります (つまり、新しいインスタンスを起動する)。 -サーキットをオープン状態にして eShopOnContainers でテストするには、いくつかの方法があります。 +すべてのコンテナーを起動するとき、'eShopOnContainers' では、上記の再試行パターンを利用してこれらの問題を解決します。 + +### eShopOnContainers でサーキット ブレーカーをテストする + +いくつかの方法でサーキットを中断し/オープン状態にし、eShopOnContainers でテストできます。 1 つの方法は、サーキット ブレーカー ポリシーで許可する再試行の数を 1 まで減らし、ソリューション全体を Docker に再展開することです。 再試行を 1 回にすることで、展開中に HTTP 要求が失敗し、サーキット ブレーカーがオープン状態になって、エラーが発生する可能性が高くなります。 -もう 1 つの方法は、`Basket` マイクロサービスで実装されているカスタムのミドルウェアを使用することです。 このミドルウェアが有効な場合、すべての HTTP 要求を捕捉し、状態コード 500 を返します。 次のように、"failing" URI に GET 要求を実行してミドルウェアを有効にできます。 +もう 1 つの方法は、Basket マイクロサービスで実装されているカスタムのミドルウェアを使用することです。 このミドルウェアが有効な場合、すべての HTTP 要求を捕捉し、状態コード 500 を返します。 次のように、"failing" URI に GET 要求を実行してミドルウェアを有効にできます。 -- GET /failing +- `GET http://localhost:5103/failing` -この要求は、ミドルウェアの現在の状態を返します。 ミドルウェアが有効な場合、要求は状態コード 500 を返します。 ミドルウェアが無効の場合、応答はありません。 +この要求は、ミドルウェアの現在の状態を返します。 ミドルウェアが有効な場合、要求は状態コード 500 を返します。 ミドルウェアが無効の場合、応答はありません。 -- GET /failing?enable +- `GET http://localhost:5103/failing?enable` -この要求はミドルウェアを有効にします。 +この要求はミドルウェアを有効にします。 -- GET /failing?disable +- `GET http://localhost:5103/failing?disable` -この要求はミドルウェアを無効にします。 +この要求はミドルウェアを無効にします。 たとえば、アプリケーションが実行されたら、任意のブラウザーで次の URI を使用して要求を実行することにより、ミドルウェアを有効にできます。 注文マイクロサービスにはポート 5103 を使用することにご注意ください。 -http://localhost:5103/failing?enable +`http://localhost:5103/failing?enable` -その後、図 10-4 に示されているように、URI [http://localhost:5103/failing](http://localhost:5103/failing) を使用して状態を確認できます。 +その後、図 10-4 に示されているように、URI http://localhost:5103/failing を使用して状態を確認できます。 ![](./media/image4.png) @@ -175,9 +105,9 @@ http://localhost:5103/failing?enable この時点で Basket マイクロサービスは、呼び出すたびに状態コード 500 を返します。 -ミドルウェアを実行したら、MVC Web アプリから注文してみることができます。 要求は失敗するため、サーキットがオープン状態になります。 +ミドルウェアを実行したら、MVC Web アプリから注文してみることができます。 要求は失敗するため、サーキットがオープン状態になります。 -次の例では、MVC Web アプリが、注文のためのロジック内に catch ブロックを含んでいることがわかります。 コードがサーキット オープンの例外を捕捉すると、ユーザーに待機を促すメッセージを表示します。 +次の例では、MVC Web アプリが、注文のためのロジック内に catch ブロックを含んでいることがわかります。 コードがサーキット オープンの例外を捕捉すると、ユーザーに待機を促すメッセージを表示します。 ```csharp public class CartController : Controller @@ -186,8 +116,11 @@ public class CartController : Controller public async Task Index() { try - { - //… Other code + { + var user = _appUserParser.Parse(HttpContext.User); + //Http requests using the Typed Client (Service Agent) + var vm = await _basketSvc.GetBasket(user); + return View(vm); } catch (BrokenCircuitException) { @@ -204,43 +137,23 @@ public class CartController : Controller } ``` -まとめます。 再試行ポリシーは、HTTP 要求の実行を数回試行し、HTTP エラーが発生します。 試行回数がサーキット ブレーカー ポリシーに設定された最大回数に達すると (この場合は 5 回)、アプリケーションは BrokenCircuitException をスローします。 結果として、図 10-5 に示されているようなメッセージが表示されます。 +まとめます。 再試行ポリシーは、HTTP 要求の実行を数回試行し、HTTP エラーが発生します。 再試行回数がサーキット ブレーカー ポリシーに設定された最大回数に達すると (この場合は 5 回)、アプリケーションは BrokenCircuitException をスローします。 結果として、図 10-5 に示されているようなメッセージが表示されます。 ![](./media/image5.png) **図 10-5**. サーキット ブレーカーが UI にエラーを返している -サーキットをいつオープン状態にするかに関して、別のロジックを実装することもできます。 または、フォールバック データセンターか冗長バックエンド システムがある場合、他のバックエンド マイクロサービスに対して HTTP 要求を試行することができます。 +サーキットをいつオープン状態にするか/中断するかに関して、別のロジックを実装できます。 または、フォールバック データセンターか冗長バックエンド システムがある場合、他のバックエンド マイクロサービスに対して HTTP 要求を試行することができます。 -最後に、CircuitBreakerPolicy の別の可能性として、Isolate (サーキットを強制的にオープン状態にし、オープン状態を維持する) と Reset (もう一度クローズド状態にする) を使用する方法があります。 これらは、ポリシーに対して Isolate と Reset を直接呼び出すユーティリティ HTTP エンドポイントを構築するために使用できます。 このような HTTP エンドポイントは、アップグレードしたい場合など、ダウンストリーム システムを一時的に分離するために運用環境で適切な安全性を保つために使用することもできます。 または、障害が発生する恐れがあるダウンストリーム システムを保護するために手動でサーキットを切断することもできます。 +最後に、`CircuitBreakerPolicy` の別の可能性として、`Isolate` (サーキットを強制的にオープン状態にし、オープン状態を維持する) と `Reset` (もう一度クローズド状態にする) を使用する方法があります。 これらは、ポリシーに対して Isolate と Reset を直接呼び出すユーティリティ HTTP エンドポイントを構築するために使用できます。 このような HTTP エンドポイントは、アップグレードしたい場合など、ダウンストリーム システムを一時的に分離するために運用環境で適切な安全性を保つために使用することもできます。 または、障害が発生する恐れがあるダウンストリーム システムを保護するために手動でサーキットを切断することもできます。 -## 再試行ポリシーにジッタ方式を追加する - -通常の再試行ポリシーは、同時実行性やスケーラビリティが高い場合や、高競合状態下でシステムに影響を及ぼすことがあります。 部分的な停止の場合に多くのクライアントから来る同様の再試行のピークを乗り越えるための賢い回避策は、ジッタ方式を再試行アルゴリズムまたはポリシーに追加することです。 これにより、急増するバックオフにランダム性を加えることで、エンドツーエンド システム全体のパフォーマンスを向上できます。 こうすれば、問題が発生した際のスパイクを分散できます。 Polly を使用する場合、ジッタを実装するコードは次の例のようになります。 - -```csharp -Random jitterer = new Random(); -Policy.Handle() // etc - .WaitAndRetry(5, // exponential back-off plus some jitter - retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)) - + TimeSpan.FromMilliseconds(jitterer.Next(0, 100)) - ); -``` ## その他の技術情報 -- **再試行パターン** - [*https://docs.microsoft.com/azure/architecture/patterns/retry*](https://docs.microsoft.com/azure/architecture/patterns/retry) - -- **接続の回復性** (Entity Framework Core) [*https://docs.microsoft.com/ef/core/miscellaneous/connection-resiliency*](https://docs.microsoft.com/ef/core/miscellaneous/connection-resiliency) - -- **Polly** (.NET の復元および一時的な障害処理ライブラリ) [*https://github.com/App-vNext/Polly*](https://github.com/App-vNext/Polly) - **サーキット ブレーカー パターン** [*https://docs.microsoft.com/azure/architecture/patterns/circuit-breaker*](https://docs.microsoft.com/azure/architecture/patterns/circuit-breaker) -- **Marc Brooker.ジッタ: ランダム性を使って状況を改善する** https://brooker.co.za/blog/2015/03/21/backoff.html - >[!div class="step-by-step"] [前へ](implement-http-call-retries-exponential-backoff-polly.md) diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/implement-http-call-retries-exponential-backoff-polly.md b/docs/standard/microservices-architecture/implement-resilient-applications/implement-http-call-retries-exponential-backoff-polly.md index 400e1630d9b..3a2de842c54 100644 --- a/docs/standard/microservices-architecture/implement-resilient-applications/implement-http-call-retries-exponential-backoff-polly.md +++ b/docs/standard/microservices-architecture/implement-resilient-applications/implement-http-call-retries-exponential-backoff-polly.md @@ -1,175 +1,92 @@ --- -title: Polly で指数のバックオフを含む HTTP 呼び出しの再試行を実装する -description: コンテナー化された .NET アプリケーションの .NET マイクロサービス アーキテクチャ | Polly で指数のバックオフを含む HTTP 呼び出しの再試行を実装する -author: CESARDELATORRE -ms.author: wiwagn -ms.date: 05/26/2017 -ms.openlocfilehash: cce1392bb381859e7cad89c9f2518113241ae724 -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37106932" +title: Polly で指数バックオフを含む HTTP 呼び出しの再試行を実装する +description: HTTP エラーを Polly と HttpClientFactory で処理する方法について説明します +author: CESARDELATORRE +ms.author: wiwagn +ms.date: 06/10/2018 +ms.openlocfilehash: c16f4c0f2ef09f346c8b46ff8089883cedcf0c7e +ms.sourcegitcommit: 59b51cd7c95c75be85bd6ef715e9ef8c85720bac +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/06/2018 +ms.locfileid: "37874898" --- -# Polly で指数のバックオフを含む HTTP 呼び出しの再試行を実装する +# HttpClientFactory ポリシーと Polly ポリシーで指数バックオフを含む HTTP 呼び出しの再試行を実装する -指数のバックオフでの再試行のためのアプローチとしては、オープン ソースである [Polly](https://github.com/App-vNext/Polly) ライブラリのような高度な .NET ライブラリを利用することをお勧めします。 +指数のバックオフでの再試行のためのアプローチとしては、オープン ソースである [Polly ライブラリ](https://github.com/App-vNext/Polly)のような高度な .NET ライブラリを利用することをお勧めします。 -Polly とは、回復機能と一時的な障害処理の機能を提供する .NET ライブラリです。 このような機能は、再試行、遮断器、バルクヘッド分離、タイムアウト、フォールバックなどの Polly ポリシーを適用することで簡単に実装できます。 Polly は .NET 4.x および .NET Standard バージョン 1.0 (.NET Core をサポート) を対象にしています。 +Polly とは、回復機能と一時的な障害処理の機能を提供する .NET ライブラリです。 このような機能は、再試行、遮断器、バルクヘッド分離、タイムアウト、フォールバックなどの Polly ポリシーを適用することで実装できます。 Polly は .NET 4.x および .NET Standard ライブラリ 1.0 (.NET Core をサポート) を対象にしています。 -Polly の再試行ポリシーは、HTTP の再試行を実装する場合に eShopOnContainers で使用されるアプローチです。 使用する再試行ポリシーの構成に応じて、標準的な HttpClient 機能か、または Polly を使用した HttpClient の回復バージョンを挿入できるように、インターフェイスを実装することができます。 +ただし、HttpClient を含む独自のコードで Polly のライブラリを使用することは非常に複雑になる可能性があります。 eShopOnContainers の最初のバージョンでは、[ResilientHttpClient ビルディングブロック](https://github.com/dotnet-architecture/eShopOnContainers/blob/master/src/BuildingBlocks/Resilience/Resilience.Http/ResilientHttpClient.cs)が Polly を基盤としていました。 しかしながら、HttpClientFactory が公開され、回復力のある HTTP 通信が簡単に実装できるようになり、eShopOnContainers ではビルディングブロックが非推奨になりました。 -次の例では、eShopOnContainers で実装されたインターフェイスを示します。 +次の手順では、前のセクションで説明した、HttpClientFactory に統合された Polly で HTTP 再試行を使用する方法を示します。 -```csharp -public interface IHttpClient -{ - Task GetStringAsync(string uri, string authorizationToken = null, - string authorizationMethod = "Bearer"); - Task PostAsync(string uri, T item, - string authorizationToken = null, string requestId = null, - string authorizationMethod = "Bearer"); +**ASP.NET Core 2.1 パッケージを参照する** - Task DeleteAsync(string uri, - string authorizationToken = null, string requestId = null, - string authorizationMethod = "Bearer"); +プロジェクトで NuGet からの ASP.NET Core 2.1 を使用する必要がある場合、 通常、`AspNetCore` メタパッケージと拡張パッケージ `Microsoft.Extensions.Http.Polly` が必要になります。 - // Other methods ... -} -``` +**Startup で、Polly の再試行ポリシーでクライアントを構成する** -簡単なアプローチを開発またはテストするときのように、回復メカニズムを使用したくない場合は、標準の実装を使用することができます。 次のコードは、省略可能なケースとして認証トークンを使用した要求を許可する標準的な HttpClient 実装を示しています。 +前のセクションで示したように、標準の Startup.ConfigureServices(...) メソッドで、名前または型が指定された HttpClient 構成を定義する必要がありますが、今後は以下のように、指数バックオフを含む HTTP 再試行のポリシーを指定し、増分コードを追加します。 ```csharp -public class StandardHttpClient : IHttpClient -{ - private HttpClient _client; - private ILogger _logger; - - public StandardHttpClient(ILogger logger) - { - _client = new HttpClient(); - _logger = logger; - } - - public async Task GetStringAsync(string uri, - string authorizationToken = null, - string authorizationMethod = "Bearer") - { - var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri); - if (authorizationToken != null) - { - requestMessage.Headers.Authorization = - new AuthenticationHeaderValue(authorizationMethod, authorizationToken); - } - var response = await _client.SendAsync(requestMessage); - return await response.Content.ReadAsStringAsync(); - } - - public async Task PostAsync(string uri, T item, - string authorizationToken = null, string requestId = null, - string authorizationMethod = "Bearer") - { - // Rest of the code and other Http methods ... +//ConfigureServices() - Startup.cs +services.AddHttpClient() + .SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Set lifetime to five minutes + .AddPolicyHandler(GetRetryPolicy()); ``` -興味深い実装は類似した別のクラスをコード化することですが、使用する回復メカニズム (次の例では、指数のバックオフでの再試行) を実装するには Polly を使用します。 +**AddPolicyHandler()** メソッドは、使用する `HttpClient` オブジェクトにポリシーを追加します。 この場合、指数バックオフを含む HTTP 再試行に対して Polly のポリシーが追加されます。 + +手法のモジュール性を高める目的で、次のコードのように、ConfigureServices() メソッド内の個別メソッドに HTTP 再試行ポリシーを定義できます。 ```csharp -public class ResilientHttpClient : IHttpClient +static IAsyncPolicy GetRetryPolicy() { - private HttpClient _client; - private PolicyWrap _policyWrapper; - private ILogger _logger; - - public ResilientHttpClient(Policy[] policies, - ILogger logger) - { - _client = new HttpClient(); - _logger = logger; - // Add Policies to be applied - _policyWrapper = Policy.WrapAsync(policies); - } - - private Task HttpInvoker(Func> action) - { - // Executes the action applying all - // the policies defined in the wrapper - return _policyWrapper.ExecuteAsync(() => action()); - } - - public Task GetStringAsync(string uri, - string authorizationToken = null, - string authorizationMethod = "Bearer") - { - return HttpInvoker(async () => - { - var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri); - // The Token's related code eliminated for clarity in code snippet - var response = await _client.SendAsync(requestMessage); - return await response.Content.ReadAsStringAsync(); - }); - } - // Other Http methods executed through HttpInvoker so it applies Polly policies - // ... + return HttpPolicyExtensions + .HandleTransientHttpError() + .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound) + .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, + retryAttempt))); } ``` -Polly では、再試行回数を指定した再試行ポリシー、指数のバックオフの構成、および HTTP 例外が発生した場合に実行するアクション (エラーの記録など) を定義します。 この場合は、IoC コンテナーでの種類の登録時に指定した回数が試行されるように、ポリシーを構成します。 指数のバックオフ構成であるために、コードは HttpRequest 例外を検出するたびに、ポリシーが構成されている方法に応じて指数関数的に増加する時間を待機してから Http 要求を再試行します。 +Polly では、再試行回数を指定した再試行ポリシー、指数バックオフの構成、HTTP 例外が発生した場合に実行するアクション (エラーの記録など) を定義できます。 上記のコードでは、指数関数的再試行で (最初は 2 秒) 6 回試すようにポリシーが構成されています。 + +つまり、6 回試すとき、再試行間の秒数が指数関数的に後退します (最初は 2 秒)。 -重要なメソッドは HttpInvoker です。これは、このユーティリティ クラス全体にわたって HTTP 要求を行うメソッドです。 そのメソッドは、\_policyWrapper.ExecuteAsync が指定された HTTP 要求を内部で実行します。これにより再試行ポリシーが考慮されます。 +### 再試行ポリシーにジッタ方式を追加する -eShopOnContainers では、次に示した [MVC Web アプリの startup.cs クラス](https://github.com/dotnet-architecture/eShopOnContainers/blob/master/src/Web/WebMVC/Startup.cs)のコードのように、IoC コンテナーで種類を登録するときに Polly ポリシーを指定します。 +通常の再試行ポリシーは、同時実行性やスケーラビリティが高い場合や、高競合状態下でシステムに影響を及ぼすことがあります。 部分的な停止の場合に多くのクライアントから来る同様の再試行のピークを乗り越えるための賢い回避策は、ジッタ方式を再試行アルゴリズムまたはポリシーに追加することです。 これにより、急増するバックオフにランダム性を加えることで、エンドツーエンド システム全体のパフォーマンスを向上できます。 こうすれば、問題が発生した際のスパイクを分散できます。 平易な Polly ポリシーを使用する場合、ジッタを実装するコードは次の例のようになります。 ```csharp -// Startup.cs class -if (Configuration.GetValue("UseResilientHttp") == bool.TrueString) -{ - services.AddTransient(); - services.AddSingleton(sp => - sp.GetService(). - CreateResilientHttpClient()); -} -else -{ - services.AddSingleton(); -} +Random jitterer = new Random(); +Policy + .Handle() // etc + .WaitAndRetry(5, // exponential back-off plus some jitter + retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)) + + TimeSpan.FromMilliseconds(jitterer.Next(0, 100)) + ); ``` -TCP 接続がサービスによって効率的に使用され、[ソケットでの問題](https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/)が発生しなくなるように、IHttpClient オブジェクトは一時的なものとしてではなく、シングルトンとしてインスタンス化されることに注意してください。 +## その他の技術情報 -ただし、回復性に関して重要な点は、次のコードに示すように、CreateResilientHttpClient メソッドの ResilientHttpClientFactory 内で Polly の WaitAndRetryAsync ポリシーを適用することです。 +- **再試行パターン** + [*https://docs.microsoft.com/azure/architecture/patterns/retry*](https://docs.microsoft.com/azure/architecture/patterns/retry) + +- **Polly と HttpClientFactory** + [*https://github.com/App-vNext/Polly/wiki/Polly-and-HttpClientFactory*](https://github.com/App-vNext/Polly/wiki/Polly-and-HttpClientFactory) + +- **Polly (.NET の復元および一時的な障害処理ライブラリ)** + + [*https://github.com/App-vNext/Polly*](https://github.com/App-vNext/Polly) + +- **Marc Brooker.ジッタ: ランダム性を使って状況を改善する** + + [*https://brooker.co.za/blog/2015/03/21/backoff.html*](https://brooker.co.za/blog/2015/03/21/backoff.html) -```csharp -public ResilientHttpClient CreateResilientHttpClient() - => new ResilientHttpClient(CreatePolicies(), _logger); - -// Other code -private Policy[] CreatePolicies() - => new Policy[] - { - Policy.Handle() - .WaitAndRetryAsync( - // number of retries - 6, - // exponential backoff - retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), - // on retry - (exception, timeSpan, retryCount, context) => - { - var msg = $"Retry {retryCount} implemented with Pollys RetryPolicy " + - $"of {context.PolicyKey} " + - $"at {context.ExecutionKey}, " + - $"due to: {exception}."; - _logger.LogWarning(msg); - _logger.LogDebug(msg); - }), - } -``` >[!div class="step-by-step"] -[前へ](implement-custom-http-call-retries-exponential-backoff.md) +[前へ](explore-custom-http-call-retries-exponential-backoff.md) [次へ](implement-circuit-breaker-pattern.md) diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/implement-resilient-entity-framework-core-sql-connections.md b/docs/standard/microservices-architecture/implement-resilient-applications/implement-resilient-entity-framework-core-sql-connections.md index 36503b92ebb..81e5308274e 100644 --- a/docs/standard/microservices-architecture/implement-resilient-applications/implement-resilient-entity-framework-core-sql-connections.md +++ b/docs/standard/microservices-architecture/implement-resilient-applications/implement-resilient-entity-framework-core-sql-connections.md @@ -1,17 +1,17 @@ --- -title: 回復力の高い Entity Framework Core SQL 接続の実装 -description: コンテナー化された .NET アプリケーションの .NET マイクロサービス アーキテクチャ | 回復力の高い Entity Framework Core SQL 接続の実装 -author: CESARDELATORRE -ms.author: wiwagn -ms.date: 05/26/2017 -ms.openlocfilehash: 79f115a2d897463c213eda6f4d6951ff0cbeb3ca -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37105476" +title: 回復力の高い Entity Framework Core SQL 接続を実装する +description: コンテナー化された .NET アプリケーションの .NET マイクロサービス アーキテクチャ | 回復力の高い Entity Framework Core SQL 接続を実装する。 この手法は、クラウドで Azure SQL Database を使用する場合に特に重要です。 +author: CESARDELATORRE +ms.author: wiwagn +ms.date: 06/08/2018 +ms.openlocfilehash: c1324eafc9dc0286128e8e942f95ad7c4c0a5d98 +ms.sourcegitcommit: 59b51cd7c95c75be85bd6ef715e9ef8c85720bac +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/06/2018 +ms.locfileid: "37874937" --- -# 回復力の高い Entity Framework Core SQL 接続の実装 +# 回復力の高い Entity Framework Core SQL 接続を実装する Azure SQL DB の場合、Entity Framework Core に内部データベース接続の復元機能と再試行ロジックが既に用意されています。 ただし、[回復力のある EF Core 接続](https://docs.microsoft.com/ef/core/miscellaneous/connection-resiliency)を使用する場合は、各 DbContext 接続に対して Entity Framework 実行戦略を有効にする必要があります。 @@ -25,13 +25,13 @@ public class Startup public IServiceProvider ConfigureServices(IServiceCollection services) { // ... - services.AddDbContext(options => + services.AddDbContext(options => { options.UseSqlServer(Configuration["ConnectionString"], sqlServerOptionsAction: sqlOptions => { sqlOptions.EnableRetryOnFailure( - maxRetryCount: 5, + maxRetryCount: 10, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); }); @@ -85,13 +85,13 @@ public async Task UpdateProduct([FromBody]CatalogItem ## その他の技術情報 +- **EF 接続の回復性** (Entity Framework Core) [*https://docs.microsoft.com/ef/core/miscellaneous/connection-resiliency*](https://docs.microsoft.com/ef/core/miscellaneous/connection-resiliency) + - **Entity Framework での接続回復性とコマンド傍受** [*https://docs.microsoft.com/azure/architecture/patterns/category/resiliency*](https://docs.microsoft.com/azure/architecture/patterns/category/resiliency) - **Cesar de la Torre。回復力の高い Entity Framework Core SQL 接続とトランザクションの使用** - >[!div class="step-by-step"] -[前へ](implement-retries-exponential-backoff.md) -[次へ](implement-custom-http-call-retries-exponential-backoff.md) +[前](implement-retries-exponential-backoff.md) [次]explore-custom-http-call-retries-exponential-backoff.md) diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/implement-retries-exponential-backoff.md b/docs/standard/microservices-architecture/implement-resilient-applications/implement-retries-exponential-backoff.md index 5442e7d4abc..ce7108f6bb9 100644 --- a/docs/standard/microservices-architecture/implement-resilient-applications/implement-retries-exponential-backoff.md +++ b/docs/standard/microservices-architecture/implement-resilient-applications/implement-retries-exponential-backoff.md @@ -1,17 +1,17 @@ --- -title: 指数バックオフを含む再試行を実装する -description: コンテナー化された .NET アプリケーションの .NET マイクロサービス アーキテクチャ | 指数バックオフを含む再試行を実装する -author: CESARDELATORRE -ms.author: wiwagn -ms.date: 05/26/2017 -ms.openlocfilehash: ee5dd711484ba7861eedbd9613fda1209736d5b6 -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37106919" +title: 指数バックオフを含む再試行を実装する +description: コンテナー化された .NET アプリケーションの .NET マイクロサービス アーキテクチャ | 指数バックオフを含む再試行を実装する +author: CESARDELATORRE +ms.author: wiwagn +ms.date: 06/08/2018 +ms.openlocfilehash: a5ab15299ecb501691c26bbc6d377e22a38ee51e +ms.sourcegitcommit: 59b51cd7c95c75be85bd6ef715e9ef8c85720bac +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/06/2018 +ms.locfileid: "37874365" --- -# 指数バックオフを含む再試行を実装する +# 指数バックオフを含む再試行を実装する [*指数バックオフを含む再試行*](https://docs.microsoft.com/azure/architecture/patterns/retry)は、最大再試行回数に達するまで、指数関数的に増加する待機時間で操作を再試行しようとする手法です ([指数バックオフ](https://en.wikipedia.org/wiki/Exponential_backoff))。 この手法を利用すると、何らかの理由でクラウド リソースが数秒以上断続的に使用できなくなる可能性があります。 たとえば、オーケストレーターは、負荷分散のためにコンテナーをクラスター内の別ノードに移動している可能性があります。 その間は、一部の要求が失敗する可能性があります。 また、SQL Azure のようなデータベースで、負荷分散のためにデータベースを別のサーバーに移動しているときに、データベースを数秒間使用できなくなる例もあります。 diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/partial-failure-strategies.md b/docs/standard/microservices-architecture/implement-resilient-applications/partial-failure-strategies.md index 8b70878d6b3..26323883ef3 100644 --- a/docs/standard/microservices-architecture/implement-resilient-applications/partial-failure-strategies.md +++ b/docs/standard/microservices-architecture/implement-resilient-applications/partial-failure-strategies.md @@ -1,15 +1,15 @@ --- -title: 部分的なエラーを処理するための戦略 -description: コンテナー化された .NET アプリケーションの .NET マイクロサービス アーキテクチャ | 部分的なエラーを処理するための戦略 -author: CESARDELATORRE -ms.author: wiwagn -ms.date: 05/26/2017 -ms.openlocfilehash: c36ea31ad19b02fb02bc8e7185bfe8687b87764f -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37104210" +title: 部分的なエラーを処理するための戦略 +description: コンテナー化された .NET アプリケーションの .NET マイクロサービス アーキテクチャ | 部分的なエラーを処理するための戦略 +author: CESARDELATORRE +ms.author: wiwagn +ms.date: 06/08/2018 +ms.openlocfilehash: ac82f6d506213614c7a4079e0f55f798f26a6550 +ms.sourcegitcommit: 59b51cd7c95c75be85bd6ef715e9ef8c85720bac +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/06/2018 +ms.locfileid: "37874404" --- # 部分的なエラーを処理するための戦略 diff --git a/docs/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests.md b/docs/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests.md new file mode 100644 index 00000000000..06ca4f48530 --- /dev/null +++ b/docs/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests.md @@ -0,0 +1,168 @@ +--- +title: HttpClientFactory を使用して回復力の高い HTTP 要求を実装する +description: HttpClientFactory は、自己主張性の強いファクトリであり、アプリケーションに使用する `HttpClient` インスタンスを作成するため、.NET Core 2.1 以降で使用できます。 +author: CESARDELATORRE +ms.author: wiwagn +ms.date: 07/03/2018 +ms.openlocfilehash: 89382f266eacc97b5e1ee5416c92dbd662427cd1 +ms.sourcegitcommit: 59b51cd7c95c75be85bd6ef715e9ef8c85720bac +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/06/2018 +ms.locfileid: "37878764" +--- +# HttpClientFactory を使用して回復力の高い HTTP 要求を実装する + +`HttpClientFactory` は、自己主張性の強いファクトリで、アプリケーションに使用する `HttpClient` インスタンスを作成するため、.NET Core 2.1 以降で使用できます。 + +## .NET Core で使用可能な元の HttpClient クラスに関する問題 + +よく知られている元の [HttpClient](https://docs.microsoft.com/dotnet/api/system.net.http.httpclient?view=netstandard-2.0) クラスは、簡単に使用できますが、多くの開発者によって適切に使用されていない場合もあります。 + +1 つ目の問題は、このクラスは破棄可能ですが、`HttpClient` オブジェクトを破棄しても、基になるソケットがすぐに解放されず、'ソケットの枯渇' という重大な問題が発生する場合があるため、`using` ステートメントで使用するのは最適な選択ではないということです。 この問題の詳細については、ブログ記事「[You're using HttpClient wrong and it is destabilizing your software](https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/)」 (HttpClient の誤った使い方がソフトウェアを不安定にする) を参照してください。 + +そのため、`HttpClient` は一度インスタンス化されたら、アプリケーションの有効期間にわたって再利用されることを目的としています。 すべての要求に対して `HttpClient` クラスをインスタンス化すると、高負荷の下で使用可能なソケットの数が枯渇してしまいます。 この問題により、`SocketException` エラーが発生します。 この問題を解決するために可能なアプローチは、HttpClient クライアントの使用に関するこの [Microsoft の記事](https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/console-webapiclient)で説明されているように、`HttpClient` オブジェクトをシングルトンまたは静的として作成することに基づいています。 + +しかし、`HttpClient` には、シングルトンまたは静的オブジェクトとして使用した場合に発生する可能性がある 2 つ目の問題があります。 この場合、[.NET Core GitHub リポジトリでこの問題](https://github.com/dotnet/corefx/issues/11224)について説明されているように、シングルトンまたは静的 `HttpClient` は、DNS の変更を尊重しません。 + +これらの問題に対処し、`HttpClient` インスタンスの管理を容易にするため、.NET Core 2.1 では、新しい `HttpClientFactory` が提供されています。これは、Polly を統合することで、回復力のある HTTP 呼び出しを実装するためにも使用できます。 + +## HttpClientFactory とは + +`HttpClientFactory` は次の目的のために設計されています。 + +- 論理 HttpClients の名前付けと構成を一元化します。 たとえば、特定のマイクロサービスにアクセスするために事前に構成されているクライアント (サービス エージェント) を構成できます。 +- `HttpClient` でのハンドラーのデリゲートにより送信ミドルウェアの概念を体系化し、Polly ベースのミドルウェアを実装して、回復性のための Polly のポリシーを利用します。 +- `HttpClient` は既に、送信 HTTP 要求用にリンクできるハンドラーのデリゲートの概念を備えています。 ファクトリに http クライアントを登録できるほか、再試行、サーキット ブレーカーなどに Polly ポリシーが使えるようになる Polly ハンドラーを使用することができます。 +- HttpClientMessageHandler の有効期間を管理して、`HttpClient` の有効期間を自分で管理する際に発生する可能性がある上記の問題を回避します。 + +## HttpClientFactory を使用する複数の方法 + +アプリケーションで `HttpClientFactory` を使用するには、複数の方法があります。 + +- `HttpClientFactory` を直接使用する +- 名前付きクライアントを使用する +- 型指定されたクライアントを使用する +- 生成されたクライアントを使用する + +説明を簡潔にするため、このガイダンスでは、型指定されたクライアント (サービス エージェント パターン) を使用するための `HttpClientFactory` を使用する最も体系化されている方法を示します。ただし、すべてのオプションは文書化されており、現在、[HttpClientFactory の使用方法を説明しているこの記事](https://docs.microsoft.com/aspnet/core/fundamentals/http-requests?#consumption-patterns)に一覧があります。 + +## HttpClientFactory で型指定されたクライアントを使用する方法 + +次の図は、HttpClientFactory で型指定されたクライアントを使用する方法を示しています。 + +![挿入された ClientService を使用する MVC コントローラーが記された図。HttpClientFactory と Polly のポリシーにより構成された HttpClient を内部的に使用しています。](./media/image3.5.png) + +**図 10-4**. 型指定されたクライアント クラスで `HttpClientFactory` を使用する + +最初に、アプリケーションで `HttpClientFactory` をセットアップします。 `IServiceCollection` の `AddHttpClient()` 拡張メソッドが含まれる `Microsoft.Extensions.Http` に参照を追加します。 この拡張メソッドは、インターフェイス `IHttpClientFactory` のシングルトンとして使用される `DefaultHttpClientFactory` を登録します。 これは `HttpMessageHandlerBuilder` の一時的な構成を定義します。 プールから取得されたこのメッセージ ハンドラー (`HttpMessageHandler` オブジェクト) は、ファクトリから返された `HttpClient` によって使用されます。 + +次のコードで、`AddHttpClient()` を使用して、`HttpClient` を使用する必要がある型指定されたクライアント (エージェント サービス) を登録する方法を確認できます。 + +```csharp +// Startup.cs +//Add http client services at ConfigureServices(IServiceCollection services) +services.AddHttpClient(); +services.AddHttpClient(); +services.AddHttpClient(); +``` + +AddHttpClient() を使用して型指定されたクライアント クラスを追加するだけで、そのコンストラクターを通じてクラスに挿入される `HttpClient` オブジェクトを使用する場合には常に、その `HttpClient` オブジェクトで提供されたすべての構成とポリシーが使用されるようになります。 以降のセクションでは、Polly の再試行またはサーキット ブレーカーのような、これらのポリシーを確認します。 + +### HttpClient の有効期間 + +IHttpClientFactory から `HttpClient` オブジェクトを取得するたび、`HttpClient` の新しいインスタンスが返されます。 型指定されたクライアントの名前ごとに HttpMessageHandler** があります。 `HttpClientFactory` は、リソースの消費量を減らすためにファクトリによって作成された HttpMessageHandler インスタンスをプールします。 新しい `HttpClient` インスタンスを作成するとき、プールの HttpMessageHandler インスタンスの有効期間が切れていない場合はそれを再利用できます。 + +通常各ハンドラーは基になる HTTP 接続を独自に管理しており、必要以上に多くのハンドラーを作成すると接続が遅延する可能性があるため、ハンドラーをプールするのは望ましい方法です。 また、一部のハンドラーは接続を無期限に開いており、DNS の変更にハンドラーが対応できないことがあります。 + +プール内の HttpMessageHandler オブジェクトには、有効期間があります。この有効期間は、プール内の HttpMessageHandler インスタンスを再利用できる期間です。 既定値は 2 分ですが、名前付きクライアントまたは型指定されたクライアントごとにオーバーライドできます。 オーバーライドするには、次のコードに示すように、クライアントを作成するときに返される IHttpClientBuilder で SetHandlerLifetime() を呼び出します。 + +```csharp +//Set 5 min as the lifetime for the HttpMessageHandler objects in the pool used for the Basket Typed Client +services.AddHttpClient() + .SetHandlerLifetime(TimeSpan.FromMinutes(5)); +``` + +型指定されたクライアントまたは名前付きクライアントには、それぞれ独自の構成済みハンドラーの有効期間の値を設定できます。 ハンドラーの有効期限を無効にするには、有効期間を InfiniteTimeSpan に設定します。 + +### 挿入された構成済みの HttpClient を使用する、型指定されたクライアント クラスを実装する + +前の手順では、型指定されたクライアント クラス (サンプル コードにある、‘BasketService’、‘CatalogService’、‘OrderingService’ のようなクラスなど) が定義されている必要がありました。型指定されたクライアントは、(そのコンストラクターを通じて挿入された) `HttpClient` オブジェクトを受け取り、それを使用していくつかのリモート HTTP サービスを呼び出すクラスです。 例: + +```csharp +public class CatalogService : ICatalogService +{ + private readonly HttpClient _httpClient; + private readonly string _remoteServiceBaseUrl; + + public CatalogService(HttpClient httpClient) + { + _httpClient = httpClient; + } + + public async Task GetCatalogItems(int page, int take, + int? brand, int? type) + { + var uri = API.Catalog.GetAllCatalogItems(_remoteServiceBaseUrl, + page, take, brand, type); + + var responseString = await _httpClient.GetStringAsync(uri); + + var catalog = JsonConvert.DeserializeObject(responseString); + return catalog; + } +} +``` + +型指定されたクライアント (この例では CatalogService) は、依存関係の挿入 (DI) によってアクティブ化されます。つまり HttpClient だけでなく、そのコンストラクター内に登録されている任意のサービスを受け取ることができます。 + +型指定されたクライアントは、実際には、一時的なオブジェクトです。つまり、新しいインスタンスは必要になるたびに作成され、新しい `HttpClient` インスタンスが構築されるたびにそれを受け取ります。 ただし、プール内の HttpMessageHandler オブジェクトは、複数の Http 要求で再利用されるオブジェクトです。 + +### 型指定されたクライアント クラスを使用する + +最後に、型クラスを実装し、それを AddHttpClient() に登録すると、DI によって挿入されたサービスがある任意の場所でそれを使用できます。たとえば、次の eShopOnContainers のコードのように、任意の Razor ページ コードや、MVC Web アプリの任意のコントローラーで使用できます。 + +```csharp +namespace Microsoft.eShopOnContainers.WebMVC.Controllers +{ + public class CatalogController : Controller + { + private ICatalogService _catalogSvc; + + public CatalogController(ICatalogService catalogSvc) => + _catalogSvc = catalogSvc; + + public async Task Index(int? BrandFilterApplied, + int? TypesFilterApplied, + int? page, + [FromQuery]string errorMsg) + { + var itemsPage = 10; + var catalog = await _catalogSvc.GetCatalogItems(page ?? 0, + itemsPage, + BrandFilterApplied, + TypesFilterApplied); + //… Additional code + } + + } +} +``` + +この時点までは、示されているコードは、通常の Http 要求を実行するだけですが、次のセクションでは、不思議なことが起こります。ポリシーを追加して、ハンドラーを登録済みの型指定されているクライアントにデリゲートするだけで、`HttpClient` によって実行されるすべての Http 要求が、指数バックオフを含む再試行、サーキット ブレーカー、またはその他の任意のカスタム デリゲート ハンドラーなど、回復力のあるポリシーを考慮して、追加のセキュリティ機能 (認証トークンの使用など) やその他のカスタム機能を実装するようになります。 + + +## その他の技術情報 + +- **.NET Core 2.1 で HttpClientFactory を使用する** + [*https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.1*](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.1) + + +- **HttpClientFactory GitHub リポジトリ** + + [*https://github.com/aspnet/HttpClientFactory*](https://github.com/aspnet/HttpClientFactory) + + + +>[!div class="step-by-step"] +[前へ] (explore-custom-http-call-retries-exponential-backoff.md) [次へ] (implement-http-call-retries-exponential-backoff-polly.md) diff --git a/docs/standard/microservices-architecture/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design.md b/docs/standard/microservices-architecture/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design.md index 0a8a37e6a3f..6ea582ce248 100644 --- a/docs/standard/microservices-architecture/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design.md +++ b/docs/standard/microservices-architecture/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design.md @@ -1,37 +1,37 @@ --- -title: インフラストラクチャの永続レイヤーの設計 -description: '.NET マイクロサービス: コンテナー化された .NET アプリケーションのアーキテクチャ | インフラストラクチャの永続レイヤーの設計' -author: CESARDELATORRE -ms.author: wiwagn -ms.date: 11/08/2017 -ms.openlocfilehash: 9da1020ac5b43971a8f976c518f4537bec866c26 -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37105847" +title: インフラストラクチャの永続レイヤーの設計 +description: インフラストラクチャの永続レイヤーを設計する方法について説明します。 +author: CESARDELATORRE +ms.author: wiwagn +ms.date: 06/28/2017 +ms.openlocfilehash: a0fcaead363e41f0dd02ed1e2ddfc90afb8d0c57 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404474" --- # インフラストラクチャの永続レイヤーの設計 -データ永続化コンポーネントは、マイクロサービス (つまり、マイクロサービスのデータベース) の境界内でホストされているデータへのアクセスを提供します。 内容としては、リポジトリや[作業単位](https://martinfowler.com/eaaCatalog/unitOfWork.html)クラス (カスタム EF DBContexts など) などのコンポーネントの実際の実装が含まれています。 +データ永続化コンポーネントは、マイクロサービス (つまり、マイクロサービスのデータベース) の境界内でホストされているデータへのアクセスを提供します。 内容としては、リポジトリや[作業単位](https://martinfowler.com/eaaCatalog/unitOfWork.html)クラス (カスタム Entity Framework (EF) など) などのコンポーネントの実際の実装が含まれています。 ## リポジトリ パターン -リポジトリは、データ ソースへのアクセスに必要なロジックをカプセル化するクラスまたはコンポーネントです。 リポジトリは一般的なデータ アクセス機能を一元管理して保守性を向上させ、ドメイン モデル レイヤーからデータベースにアクセスするためのインフラストラクチャやテクノロジを切り離します。 Entity Framework などの ORM を使用する場合、LINQ と厳密な型指定により、実装する必要があるコードが簡素化されます。 これによりデータ アクセスの組み込みではなく、データ永続化ロジックに集中できるようになります。 +リポジトリは、データ ソースへのアクセスに必要なロジックをカプセル化するクラスまたはコンポーネントです。 リポジトリは一般的なデータ アクセス機能を一元管理して保守性を向上させ、ドメイン モデル レイヤーからデータベースにアクセスするためのインフラストラクチャやテクノロジを切り離します。 Entity Framework などのオブジェクト リレーショナル マップ (ORM) を使用する場合、LINQ と厳密な型指定により、実装する必要があるコードが簡素化されます。 これによりデータ アクセスの組み込みではなく、データ永続化ロジックに集中できるようになります。 リポジトリ パターンは、ドキュメントが整備されたデータ ソース操作方法です。 Martin Fowler は、著書『[エンタープライズ アプリケーション アーキテクチャ パターン](https://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420/)』の中でリポジトリのことを次のように述べています。 -リポジトリは、ドメイン モデル レイヤーとデータ マッピングの間を媒介するタスクを実行し、メモリ内のドメイン オブジェクト セットに似たような動作をする。 クライアント オブジェクトは宣言によってクエリを構築し、リポジトリに送信して回答を得る。 概念上、リポジトリはデータベースに格納されている一連のオブジェクトとオブジェクト上で実行可能な操作をカプセル化し、永続レイヤーに近い方法を提供する。 また、リポジトリは、作業ドメインとデータの割り当て、すなわちマッピングとの依存関係を明確かつ一方向に切り離すという目的をサポートする。 +> リポジトリは、ドメイン モデル レイヤーとデータ マッピングの間を媒介するタスクを実行し、メモリ内のドメイン オブジェクト セットに似たような動作をする。 クライアント オブジェクトは宣言によってクエリを構築し、リポジトリに送信して回答を得る。 概念上、リポジトリはデータベースに格納されている一連のオブジェクトとオブジェクト上で実行可能な操作をカプセル化し、永続レイヤーに近い方法を提供する。 また、リポジトリは、作業ドメインとデータの割り当て、すなわちマッピングとの依存関係を明確かつ一方向に切り離すという目的をサポートする。 ### 集約ごとにリポジトリを定義する -各集約または集約ルートに1 つのリポジトリ クラスを作成する必要があります。 ドメイン駆動設計パターンに基づくマイクロサービスでは、リポジトリはデータベースの更新に使用する唯一のチャネルです。 これは、リポジトリには集約ルートとの一対一の関係があるためで、これにより集約の不変性とトランザクションの一貫性が管理されます。 データベースのクエリは他のチャネルで実行することもできますが (CQRS アプローチに従って実行することも可能)、それは、クエリではデータベースの状態が変更されないためです。 トランザクション領域が更新の場合は、常にリポジトリと集約ルートで制御する必要があります。 +各集約または集約ルートに1 つのリポジトリ クラスを作成する必要があります。 ドメイン駆動設計 (DDD) パターンに基づくマイクロサービスでは、リポジトリはデータベースの更新に使用する唯一のチャネルです。 これは、リポジトリには集約ルートとの一対一の関係があるためで、これにより集約の不変性とトランザクションの一貫性が管理されます。 データベースのクエリは他のチャネルで実行することもできますが (CQRS アプローチに従って実行することも可能)、それは、クエリではデータベースの状態が変更されないためです。 ただし、トランザクション領域 (つまり、更新) は、常にリポジトリと集約ルートで制御する必要があります。 基本的に、リポジトリでは、データベースから取得されたデータをドメイン エンティティの形式でメモリ内に設定することができます。 メモリ内に設定されたエンティティは、トランザクションによって変更し、再度データベースに保存することができます。 -前述したように、CQS/CQRS アーキテクチャ パターンを使用している場合、Dapper を使用した単純な SQL ステートメントによって実行されるドメイン モデルからの副クエリによって最初のクエリが実行されます。 この方法は、必要な任意のテーブルを照会および結合可能で、クエリが集約からのルールによって制限されないため、リポジトリよりはるかに柔軟です。 その場合、データはプレゼンテーション層またはクライアント アプリに遷移します。 +前述したように、CQS/CQRS アーキテクチャ パターンを使用している場合、Dapper を使用した単純な SQL ステートメントによって実行されるドメイン モデルからの副クエリによって最初のクエリが実行されます。 この方法は、必要な任意のテーブルを照会および結合可能で、クエリが集約からのルールによって制限されないため、リポジトリよりはるかに柔軟です。 その場合、データはプレゼンテーション レイヤーまたはクライアント アプリに移動します。 -ユーザーが変更を行うと、更新データはクライアント アプリまたはプレゼンテーション層からアプリケーション層 (Web API サービスなど) に移動します。 コマンド ハンドラーでコマンド (とデータ) を受信したら、リポジトリを使用して、更新するデータをデータベースから取得します。 メモリ内で、コマンドを使用して渡された情報を更新した後、トランザクションによりデータベース内のデータ (ドメイン エンティティ) を追加または更新します。 +ユーザーが変更を行うと、更新されるデータは、クライアント アプリまたはプレゼンテーション レイヤーからアプリケーションレイヤー (Web API サービスなど) に移動します。 コマンド ハンドラーでコマンドとデータを受信したら、リポジトリを使用して、更新するデータをデータベースから取得します。 メモリ内で、コマンドを使用して渡された情報を更新した後、トランザクションによりデータベース内のデータ (ドメイン エンティティ) を追加または更新します。 図 9-17 に示すように、各集約ルートに定義するリポジトリは 1 つだけであることに注意してください。 集約内のすべてのオブジェクト間のトランザクションの一貫性を維持するという集約ルートの目標を達成するため、データベース内の各テーブルのリポジトリは作成しません。 @@ -41,7 +41,7 @@ ms.locfileid: "37105847" ### リポジトリごとに 1 つの集約ルートを適用 -リポジトリ設計を実装する際に、集約ルートのみにリポジトリを設定するというルールを適用することが重要な場合があります。 操作するエンティティの型を制約するジェネリック型または基本型のリポジトリを作成し、IAggregateRoot マーカー インターフェイスを設定することができます。 +リポジトリ設計を実装する際に、集約ルートのみにリポジトリを設定するというルールを適用することが重要な場合があります。 操作するエンティティの型を制約するジェネリック型または基本型のリポジトリを作成し、`IAggregateRoot` マーカー インターフェイスを設定することができます。 このように、インフラストラクチャ レイヤーで実装されている各リポジトリ クラスに独自のコントラクトまたはインターフェイスが実装されます (次のコードを参照)。 @@ -50,6 +50,9 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositor { public class OrderRepository : IOrderRepository { + // ... + } +} ``` リポジトリの各インターフェイスには、ジェネリック IRepository インターフェイスが実装されます。 @@ -62,60 +65,63 @@ public interface IOrderRepository : IRepository } ``` -ただし、コードが、規則を適用する優れた方法として、特定の集約を対象とするリポジトリを使用している明示的なので、汎用的なリポジトリの種類を実装すること、1 つの集約に各リポジトリを関連付ける必要があります。 これは、次のコードのように、そのジェネリックを IRepository 基底インターフェイスで実装することで簡単に行えます。 +しかし、各リポジトリが単一の集計に関連付けられる規則を適用するコードを用意するには、ジェネリック型のリポジトリを実装することをお勧めします。 そうすることで、特定の集約を対象とするリポジトリを使用していることが明確になります。 これは、次のコードのように、そのジェネリックの `IRepository` 基底インターフェイスを実装することで簡単に行えます。 ```csharp - public interface IRepository where T : IAggregateRoot +public interface IRepository where T : IAggregateRoot +{ + //.... +} ``` ### アプリケーション ロジックのテストを容易にするリポジトリ パターン リポジトリ パターンを利用すると、単体テストでアプリケーションを簡単にテストすることができます。 単体テストの対象はインフラストラクチャではなく、コードのみであるため、リポジトリの抽象化により目的を達成しやすくなります。 -前のセクションで説明したように、リポジトリ インターフェイスをドメイン モデル レイヤーに定義および配置し、アプリケーション レイヤー (たとえば Web API マイクロサービス) が、実際のリポジトリ クラスを実装しているインフラストラクチャ レイヤーに直接依存しないようにすることをお勧めします。 これにより、Web API のコント ローラーで依存関係の挿入を使用して、データベースのデータではなく疑似データを返すモック リポジトリを実装できます。 このような分離アプローチでは、データベースへの接続を必要とせず、アプリケーションのロジックだけをテストする単位テストを作成し、実行することができます。 +前のセクションで説明したように、リポジトリ インターフェイスをドメイン モデル レイヤーに定義および配置し、アプリケーション レイヤー (Web API マイクロサービスなど) が、実際のリポジトリ クラスを実装しているインフラストラクチャ レイヤーに直接依存しないようにすることをお勧めします。 これにより、Web API のコント ローラーで依存関係の挿入を使用して、データベースのデータではなく疑似データを返すモック リポジトリを実装できます。 このような分離アプローチでは、データベースへの接続を必要とせず、アプリケーションのロジックだけをテストする単体テストを作成し、実行することができます。 -データベースに対して膨大なテストを実行することには、データベースへの接続が失敗する可能性があることに加え、さらに大きな 2 つの理由から問題があります。 その一つは、テスト量の多さにより時間がかかる可能性があることです。 もう一つは、データベースのレコードが変更され、テスト結果に影響して、データの一貫性がなくなる可能性があるということです。 データベースに対するテストは単体テストではなく、統合テストです。 多数の単体テストを高速で実行する必要がありますが、データベースに対する統合テストは大量に行う必要はありません。 +データベースに対して膨大なテストを実行することには、データベースへの接続が失敗する可能性があることに加え、さらに大きな 2 つの理由から問題があります。 その 1 つは、テスト量の多さにより時間がかかる可能性があることです。 もう一つは、データベースのレコードが変更され、テスト結果に影響して、データの一貫性がなくなる可能性があるということです。 データベースに対するテストは単体テストではなく、統合テストです。 多数の単体テストを高速で実行する必要がありますが、データベースに対する統合テストは大量に行う必要はありません。 単体テストの問題の分離という観点から、ロジックはメモリ内のドメイン エンティティで動作します。 ドメイン エンティティはリポジトリ クラスで提供されるものと想定します。 また、ロジックによって変更されたドメイン エンティティは、リポジトリ クラスに適切に保存されるものと想定します。 ここでの重要なポイントは、単体テストはドメイン モデルとそのドメイン ロジックに対して作成するということです。 集約ルートは DDD の主な整合性境界です。 ### リポジトリ パターンと、従来のデータ アクセス クラス (DAL クラス) パターンの違い -データ アクセス オブジェクトは、データ アクセスおよび永続化操作を記憶域に対して直接実行します。 リポジトリは、メモリ内の作業単位オブジェクトの操作対象データにマークを付け (例: DbContext を使用する場合の EF)、更新はすぐには実行しません。 +データ アクセス オブジェクトは、データ アクセスおよび永続化操作を記憶域に対して直接実行します。 リポジトリでは、メモリ内の作業単位オブジェクトの操作対象データにマークを付けますが (例: クラスを使用する場合の EF)、更新はすぐには実行されません。 -作業単位は複数の挿入、更新、または削除操作が関与する単一のトランザクションとして表されます。 つまり、特定のユーザー操作 (たとえば Web サイトへの登録) に対して、すべての挿入、更新、および削除のトランザクションが 1 つのトランザクションとして処理されることを意味します。 これは、複数のデータベース トランザクションを対話方法で処理するよりも効率的です。 +作業単位は複数の挿入、更新、または削除操作が関与する単一のトランザクションとして表されます。 つまり、特定のユーザー操作 (Web サイトへの登録など) に対して、すべての挿入、更新、および削除のトランザクションが単一のトランザクションとして処理されることを意味します。 これは、複数のデータベース トランザクションを対話方法で処理するよりも効率的です。 -これらの複数の永続化操作は、後でアプリケーション レイヤーのコードが命令を発行したときに、1 アクションで実行されます。 実際のデータベース記憶域にメモリ内の変更を適用する決定は、通常、[作業単位パターン](https://martinfowler.com/eaaCatalog/unitOfWork.html)に基づいて行われます。 EF には、作業単位パターンは DBContext として実装されます。 +これらの複数の永続化操作は、後でアプリケーション レイヤーのコードが命令を発行したときに、1 アクションで実行されます。 実際のデータベース記憶域にメモリ内の変更を適用する決定は、通常、[作業単位パターン](https://martinfowler.com/eaaCatalog/unitOfWork.html)に基づいて行われます。 EF には、作業単位パターンは として実装されます。 -多くの場合、このパターンまたは記憶域に対する操作の適用方法により、アプリケーションのパフォーマンスを向上させ、不整合の可能性を低減することができます。 また、意図したすべての操作が 1 つのトランザクションの一部としてコミットされるので、データベース テーブル内でブロックされるトランザクションが少なくなります。 これは、データベースに対して多数の単独の操作を実行する場合と比べて効率的です。 そのため、小規模な単独のトランザクションを多数実行するのではなく、同じトランザクション内で複数の更新操作をグループ化することにより、選択した ORM でデータベースに対する実行を最適化できます。 +多くの場合、このパターンまたは記憶域に対する操作の適用方法により、アプリケーションのパフォーマンスを向上させ、不整合の可能性を低減することができます。 また、意図したすべての操作が単一のトランザクションの一部としてコミットされるので、データベース テーブル内でブロックされるトランザクションも少なくなります。 これは、データベースに対して多数の単独の操作を実行する場合と比べて効率的です。 そのため、小規模な個別のトランザクションを多数実行するのではなく、同じトランザクション内で複数の更新操作をグループ化することにより、選択した ORM でデータベースに対する実行を最適化できます。 -### リポジトリは必須ではない +### リポジトリは必須ではない -カスタム リポジトリは、前述の理由により便利であり、eShopOnContainers の順序付けマイクロサービスで採用されているアプローチですが、 DDD 設計の実装、または .NET での開発全般に不可欠なパターンではありません。 +カスタム リポジトリは、前述の理由により便利であり、eShopOnContainers の順序付けマイクロサービスで採用されているアプローチですが、 DDD 設計の実装、または一般的な .NET 開発に不可欠なパターンではありません。 たとえば、このガイドに対するフィードバックを直接提供してくれた Jimmy Bogard は次のように述べています。 -おそらく、これは私の最大のフィードバックになるでしょう。 私はリポジトリが好きではありません。その主な理由は、基本となる永続化メカニズムの重要な詳細が隠ぺいされていることです。 私がコマンドに MediatR を採用する理由もそこにあります。 永続レイヤーの機能をフルに活用し、集約ルートにドメイン動作のすべてをプッシュすることができます。 通常は、リポジトリでのシミュレーションを行いたくないので、実際のデータで統合テストを実行する必要があります。 CQRS を利用すれば、もうリポジトリは不要です。 +> おそらく、これは私の最大のフィードバックになるでしょう。 私はリポジトリが好きではありません。その主な理由は、基本となる永続化メカニズムの重要な詳細が隠ぺいされていることです。 私がコマンドに MediatR を採用する理由もそこにあります。 永続レイヤーの機能をフルに活用し、集約ルートにドメイン動作のすべてをプッシュすることができます。 通常は、リポジトリでのシミュレーションを行いたくないので、実際のデータで統合テストを実行する必要があります。 CQRS を利用すれば、もうリポジトリは不要です。 -リポジトリが便利であることはわかっていますが、集約パターンやリッチ ドメイン モデルとは異なり、DDD においてリポジトリは不可欠ではありません。 したがって、リポジトリ パターンは使用しても、しなくても、かまいません。 +リポジトリは便利ですが、集約パターンやリッチ ドメイン モデルとは異なり、DDD においてリポジトリは不可欠ではありません。 したがって、リポジトリ パターンは使用しても、しなくても、かまいません。 ## 仕様パターン -仕様パターン (正式名称はクエリ仕様パターン) は、並べ替え/ページング ロジックを指定可能なクエリ定義を配置する場所として設けられたドメイン駆動設計パターンです。 +仕様パターン (正式名称はクエリ仕様パターン) は、並べ替え/ページング ロジックを指定可能なクエリ定義を配置する場所として設けられた DDD パターンです。 -仕様パターンではクエリをオブジェクトに定義します。 たとえば、必要な入力パラメーター (pageNumber、pageSize、filter など) を受け取る PagedProduct 仕様を作成することで、製品を検索するページ指定クエリをカプセル化できます。 その後、Repository の任意のメソッド (通常は List() オーバーロード) 内で、ISpecification を受け取り、その仕様に基づいて予想されるクエリを実行します。 +仕様パターンによって、オブジェクトのクエリが定義されます。 たとえば、必要な入力パラメーター (`pageNumber`、`pageSize`、`filter` など) を受け取る `PagedProduct` 仕様を作成することで、製品を検索するページ指定クエリをカプセル化できます。その後、任意のリポジトリ メソッド (通常は List() オーバーロード) 内で、`ISpecification` を受け取り、その仕様に基づいて予想されるクエリを実行します。 このアプローチにはいくつかの利点があります。 -* 仕様には議論の余地のある名前 (単なる一連の LINQ 式ではなく) が付いています。 +- 仕様には議論の余地のある名前 (単なる一連の LINQ 式ではなく) が付いています。 -* 仕様単独で単位テストを実行し、適切であることを確認できます。 同様の動作が必要な場合に、仕様を容易に再利用できます。 たとえば、MVC ビュー アクションと Web API アクション、およびさまざまなサービスで仕様を再利用できます。 +- 仕様は単独で単体テストを実行し、適切であることを確認できます。 同様の動作が必要な場合に、仕様を容易に再利用できます。 たとえば、MVC ビュー アクションと Web API アクション、およびさまざまなサービスで仕様を再利用できます。 -* 仕様は、返されるデータの構造の記述にも使用できるため、クエリで必要なデータだけを返すことができます。 これにより、Web アプリケーションの遅延読み込み (通常はお勧めできない操作) の必要がなくなり、リポジトリの実装にこうした繁雑な詳細を取り入れずに済みます。 +- 仕様は、返されるデータの構造の記述にも使用できるため、クエリで必要なデータだけを返すことができます。 これにより、Web アプリケーションの遅延読み込み (通常はお勧めできない操作) の必要がなくなり、リポジトリの実装にこうした繁雑な詳細を取り入れずに済みます。 -一般的な Specification (仕様) インターフェイスの例として、[eShopOnWeb](https://github.com/dotnet-architecture/eShopOnWeb ) から抜粋した次のコードをご覧ください。 +一般的な仕様インターフェイスの例として、[eShopOnWeb](https://github.com/dotnet-architecture/eShopOnWeb) から抜粋した次のコードをご覧ください。 ```csharp -// https://github.com/dotnet-architecture/eShopOnWeb +// https://github.com/dotnet-architecture/eShopOnWeb public interface ISpecification { Expression> Criteria { get; } @@ -124,44 +130,43 @@ public interface ISpecification } ``` -次のセクションでは、仕様パターンを Entity Framework Core 2.0 で実装する方法と、任意の Repository (リポジトリ) クラスから使用する方法を説明します。 +次のセクションでは、仕様パターンを EF Core 2.x で実装する方法と、任意のリポジトリ クラスから使用する方法を説明します。 -**重要な注意事項:** 仕様パターンは、次の「その他の技術情報」のセクションに示されているように、さまざまな方法で実装できる古いパターンです。 パターンやアイデアとしては古いアプローチがわかりやすいかもしれませんが、Linq や式のような最新の言語機能を利用していない古い実装には注意が必要です。 +> [!IMPORTANT] +> 仕様パターンは、次の「その他の技術情報」セクションに示されているように、さまざまな方法で実装できる古いパターンです。 パターンやアイデアとしては古いアプローチがわかりやすいかもしれませんが、Linq や式のような最新の言語機能を利用していない古い実装には注意が必要です。 ## その他の技術情報 ### リポジトリ パターン -- **Edward Hieatt、Rob Mee。リポジトリ パターン。** - [*https://martinfowler.com/eaaCatalog/repository.html*](https://martinfowler.com/eaaCatalog/repository.html) +- **リポジトリ パターン** + [https://deviq.com/repository-pattern/](https://deviq.com/repository-pattern/) -- **リポジトリ パターン** - [*https://msdn.microsoft.com/library/ff649690.aspx*](https://msdn.microsoft.com/library/ff649690.aspx) +- **Edward Hieatt、Rob Mee。リポジトリ パターン。** + [_https://martinfowler.com/eaaCatalog/repository.html_](https://martinfowler.com/eaaCatalog/repository.html) -- **リポジトリ パターン: データ永続性の抽象化** - [*http://deviq.com/repository-pattern/*](http://deviq.com/repository-pattern/) +- **リポジトリ パターン** + [_https://docs.microsoft.com/previous-versions/msp-n-p/ff649690(v=pandp.10)_](https://docs.microsoft.com/previous-versions/msp-n-p/ff649690(v=pandp.10)) -- **Eric Evans。Domain-Driven Design: Tackling Complexity in the Heart of Software (ドメイン駆動設計: ソフトウェア中心部の複雑さへの取り組み)。** (書籍: リポジトリ パターンに関する説明が含まれています) [*https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/*](https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/) +- **Eric Evans。Domain-Driven Design: Tackling Complexity in the Heart of Software (ドメイン駆動設計: ソフトウェア中心部の複雑さへの取り組み)。** (書籍: リポジトリ パターンに関する説明が含まれています) [_https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/_](https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/) ### Unit of Work パターン -- **Martin Fowler。Unit of Work パターン。** - [*https://martinfowler.com/eaaCatalog/unitOfWork.html*](https://martinfowler.com/eaaCatalog/unitOfWork.html) - - +- **Martin Fowler。Unit of Work パターン。** + [_https://martinfowler.com/eaaCatalog/unitOfWork.html_](https://martinfowler.com/eaaCatalog/unitOfWork.html) -- **ASP.NET MVC アプリケーションでの Repository および Unit of Work パターンの実装** - [*https://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application*](https://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application) +- **ASP.NET MVC アプリケーションでの Repository および Unit of Work パターンの実装** + [_https://docs.microsoft.com/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application_](https://docs.microsoft.com/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application) ### 仕様パターン -- **仕様パターン。** - [*http://deviq.com/specification-pattern/*](http://deviq.com/specification-pattern/) +- **仕様パターン。** + [_https://deviq.com/specification-pattern/_](https://deviq.com/specification-pattern/) -- **Evans, Eric (2004 年)。「Domain Driven Design」(ドメイン駆動設計)。Addison-Wesley. p. 224.** +- **Evans, Eric (2004 年)。「Domain Driven Design」(ドメイン駆動設計)。Addison-Wesley. p. 224.** -- **「Specifications」(仕様)。Martin Fowler** - [*https://www.martinfowler.com/apsupp/spec.pdf/*](https://www.martinfowler.com/apsupp/spec.pdf) +- **「Specifications」(仕様)。Martin Fowler** + [_https://www.martinfowler.com/apsupp/spec.pdf/_](https://www.martinfowler.com/apsupp/spec.pdf) >[!div class="step-by-step"] [前へ](domain-events-design-implementation.md) diff --git a/docs/standard/modern-web-apps-azure-architecture/architectural-principles.md b/docs/standard/modern-web-apps-azure-architecture/architectural-principles.md index 7444d8bf051..0acd6ab8478 100644 --- a/docs/standard/modern-web-apps-azure-architecture/architectural-principles.md +++ b/docs/standard/modern-web-apps-azure-architecture/architectural-principles.md @@ -1,23 +1,21 @@ --- -title: アーキテクチャの原則 -description: ASP.NET Core および Azure での最新の Web アプリケーションの設計 | アーキテクチャの原則 -author: ardalis -ms.author: wiwagn -ms.date: 10/06/2017 -ms.openlocfilehash: 4ee14b128d3b83fd446352bb6f78afc08fb38c52 -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37105860" +title: アーキテクチャの原則 +description: ASP.NET Core および Azure での最新の Web アプリケーションの設計 | アーキテクチャの原則 +author: ardalis +ms.author: wiwagn +ms.date: 6/28/2018 +ms.openlocfilehash: 2e0938fc67e02a52b99158b2ff07b9f32464e674 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404439" --- # アーキテクチャの原則 > "プログラマーがプログラムを記述するやり方で建設業者がビルを建てたなら、最初にやって来たキツツキによって文明は破壊されてしまうでしょう。" > _\- Gerald Weinberg_ -## まとめ - ソフトウェア ソリューションを設計する場合は、保守容易性を念頭に置く必要があります。 このセクションで概説する原則は、クリーンで保守性の高いアプリケーションをもたらすアーキテクチャを決定する上で役に立ちます。 一般に、これらの原則に従うことで、明示的なインターフェイスまたはメッセージング システムを介してやり取りするコンポーネントでなく、アプリケーションの他の部分と密結合されていないそれぞれ独立したコンポーネントからアプリケーションを構築できるようになります。 ## 一般的な設計の原則 @@ -64,7 +62,7 @@ ms.locfileid: "37105860" この原則がアプリケーション アーキテクチャに適用され、その論理エンドポイントに到達すると、マイクロサービスが得られます。 指定されたマイクロサービスは、単一責任を持つ必要があります。 システムのビヘイビアーを拡張する必要がある場合は、既存の責任にさらに責任を追加するのでなく、別のマイクロサービスを追加することによって目的を達成することをお勧めします。 -[マイクロサービス アーキテクチャの詳細](http://aka.ms/MicroservicesEbook) +[マイクロサービス アーキテクチャの詳細](https://aka.ms/MicroservicesEbook) ### DRY 原則 @@ -81,17 +79,17 @@ ms.locfileid: "37105860" この原則に対する違反の例を次に示します。 -- 必要な基本クラス +- 必要な基本クラス -- 必要なインターフェイスの実装 +- 必要なインターフェイスの実装 -- 自身を保存する責任のあるクラス ("アクティブ レコード" パターンなど) +- 自身を保存する責任のあるクラス ("アクティブ レコード" パターンなど) -- 必要な既定のコンストラクター +- 必要な既定のコンストラクター -- 仮想キーワードを必要とするプロパティ +- 仮想キーワードを必要とするプロパティ -- 必要とされる永続化に固有の属性 +- 必要とされる永続化に固有の属性 上記のいずれかの機能またはビヘイビアーがクラスに含まれる必要があるという要件では、永続化する型と永続化技術の選択肢との間に結合が追加されるため、後で新しいデータ アクセス方法を採用することが難しくなります。 @@ -103,19 +101,20 @@ ms.locfileid: "37105860" > ### 参照 – 最新の Web アプリケーション > - **懸念事項の分離** -> -> - **カプセル化** +> +> - **カプセル化** +> > - **依存関係逆転の原則** -> +> > - **明示的な依存関係の原則** -> +> > - **DRY 原則** -> +> > - **永続性の無視** -> +> > - **境界付けられたコンテキスト** > -> [!div class="step-by-step"] +>[!div class="step-by-step"] [前へ](choose-between-traditional-web-and-single-page-apps.md) [次へ](common-web-application-architectures.md) diff --git a/docs/standard/modern-web-apps-azure-architecture/azure-hosting-recommendations-for-asp-net-web-apps.md b/docs/standard/modern-web-apps-azure-architecture/azure-hosting-recommendations-for-asp-net-web-apps.md index a00a68b5a82..0da8f586f4f 100644 --- a/docs/standard/modern-web-apps-azure-architecture/azure-hosting-recommendations-for-asp-net-web-apps.md +++ b/docs/standard/modern-web-apps-azure-architecture/azure-hosting-recommendations-for-asp-net-web-apps.md @@ -1,66 +1,65 @@ --- -title: ASP.NET Core Web アプリ用の Azure ホスティングの推奨事項 -description: ASP.NET Core および Azure での最新の Web アプリケーションの設計 | ASP.NET Web アプリ用の Azure ホスティングの推奨事項 -author: ardalis -ms.author: wiwagn -ms.date: 10/07/2017 -ms.openlocfilehash: 756f74cacec0a9f5be502ee02659510869d79746 -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37105710" +title: ASP.NET Core Web アプリ用の Azure ホスティングの推奨事項 +description: ASP.NET Core および Azure での最新の Web アプリケーションの設計 | ASP.NET Web アプリ用の Azure ホスティングの推奨事項 +author: ardalis +ms.author: wiwagn +ms.date: 06/27/2018 +ms.openlocfilehash: a70cb822c789638ca107b090d1aed2b88ccc6a5d +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404529" --- # ASP.NET Core Web アプリ用の Azure ホスティングの推奨事項 > "基幹業務のリーダーはどこでも、IT 部門を通さずにクラウドからアプリケーションにアクセスし (別名 SaaS)、雑誌を購読するかのように料金を支払っています。 そして、サービスが不要になったら、無駄なくサブスクリプションを取り消すことができます。" > _\- Daryl Plummer、Gartner アナリスト_ -## まとめ - -Windows Azure なら、アプリケーションのニーズとアーキテクチャに応じたサポートが可能です。 ホスティングのニーズは多数のサービスで構成される非常に高度なアプリケーションの静的な Web サイトと同じくらい簡単にできます。 ASP.NET Core のモノリシックな Web アプリケーションとサポートされるサービスには、推奨されるいくつかのよく知られている構成が含まれています。 次の推奨事項は完全なアプリケーションか、個別のプロセスか、またはデータかの、ホスティングされるリソースの種類に応じてグループ化されています。 +Windows Azure なら、アプリケーションのニーズとアーキテクチャに応じたサポートが可能です。 ホスティングのニーズは多数のサービスで構成される高度なアプリケーションの静的な Web サイトと同じくらい簡単にできます。 ASP.NET Core のモノリシックな Web アプリケーションとサポートされるサービスには、推奨されるいくつかのよく知られている構成が含まれています。 この記事の推奨事項は、完全なアプリケーション、個別のプロセス、またはデータであっても、ホスティングされるリソースの種類に基づいてグループ化されています。 ## Web アプリケーション Web アプリケーションは次を使用してホスティングできます。 -- App Service Web Apps +- App Service Web Apps -- コンテナー +- コンテナー -- Azure Service Fabric +- Azure Service Fabric -- 仮想マシン (VM) +- 仮想マシン (VM) -このうち、ほとんどのシナリオでお勧めできる手法が App Service Web Apps です。 マイクロサービス アーキテクチャでは、コンテナー ベースの方法、またはサービス ファブリックを検討してください。 アプリケーションを実行しているマシンをさらに制御する必要がある場合は、Azure Virtual Machines を検討してください。 +このうち、ほとんどのシナリオでお勧めできる手法が App Service Web Apps です。 マイクロサービス アーキテクチャでは、コンテナー ベースの方法、または Service Fabric を検討してください。 アプリケーションを実行しているマシンをさらに制御する必要がある場合は、Azure Virtual Machines を検討してください。 ### App Service Web Apps App Service Web Apps は、Web アプリケーションのホスティングに最適化されたフル マネージド プラットフォームを提供します。 これは、サービスとしてのプラットフォーム (PaaS) 製品です。Azure がアプリの実行とスケーリングに必要なインフラストラクチャに対処するため、ビジネス ロジックに集中することができます。 App Service Web Apps の主な機能: -- DevOps の最適化 (継続的インテグレーションと継続的配信、複数の環境、A/B テスト、スクリプトのサポート) +- DevOps の最適化 (継続的インテグレーションと継続的配信、複数の環境、A/B テスト、スクリプトのサポート) -- グローバルなスケーリングと高可用性 +- グローバルなスケーリングと高可用性 -- SaaS プラットフォームとオンプレミス データへの接続 +- SaaS プラットフォームとオンプレミス データへの接続 -- セキュリティとコンプライアンス +- セキュリティとコンプライアンス -- Visual Studio の統合環境 +- Visual Studio の統合 Azure App Service は、ほとんどの Web アプリに最適な選択肢です。 デプロイと管理はプラットフォームに統合されており、サイトは高い負荷を処理できるように素早くスケーリングでき、組み込みの負荷分散とトラフィック マネージャーが高可用性を提供します。 オンライン移行ツールを使用して既存のサイトを簡単に Azure App Service に移動したり、Web アプリケーション ギャラリーからオープンソース アプリを使用したり、選択したフレームワークとツールを使用して新しいサイトを作成したりできます。 Web ジョブ機能により、バックグラウンド ジョブ処理を App Service Web アプリに簡単に追加できます。 -### コンテナーと Azure Container Service - -Azure Container Service によって、コンテナー化されたアプリケーションを実行するように事前に構成されている仮想マシンのクラスターを簡単に作成、構成、管理できるようになります。 一般的なオープンソースのスケジューリングとオーケストレーション ツールの最適化された構成が使用されます。 これにより、コンテナー ベースのアプリケーションを Microsoft Azure でデプロイして管理するための専門知識を持つ増加し続けるコミュニティを利用するか、既存のスキルを使用することができます。 +### Azure Kubernetes Service -Azure Container Service によって、コンテナー化されたアプリケーションを実行するように事前に構成されている仮想マシンのクラスターを簡単に作成、構成、管理できるようになります。 一般的なオープンソースのスケジューリングとオーケストレーション ツールの最適化された構成が使用されます。 これにより、コンテナー ベースのアプリケーションを Microsoft Azure でデプロイして管理するための専門知識を持つ増加し続けるコミュニティを利用するか、既存のスキルを使用することができます。 +Azure Kubernetes Service (AKS) は、ホストされている Kubernetes 環境を管理するサービスで、コンテナー オーケストレーションの専門知識がなくても、コンテナー化したアプリケーションのデプロイと管理をすばやく簡単に行うことができます。 また、アプリケーションをオフラインにせずに、オンデマンドでリソースのプロビジョニング、アップグレード、スケーリングを実行できるため、継続的に行う操作と保守の負担も解消されます。 -Azure Container Service の目的の 1 つに、現在の Microsoft のお客様の間で一般的に使用されているオープンソース ツールとテクノロジを使用して、コンテナーのホスト環境を提供することがあります。 このため、Azure Container Service は選択したオーケストレーター (DC/OS、Docker Swarm、または Kubernetes) の標準 API エンドポイントを公開しています。 これらのエンドポイントを使用して、エンドポイントとの通信が可能な任意のソフトウェアを活用できます。 たとえば、Docker Swarm エンドポイントの場合、Docker コマンド ライン インターフェイス (CLI) を使用するよう選択できます。 DC/OS では、DCOS CLI を選択できます。 Kubernetes では、kubectl を選択できます。 図 11-1 は、これらのエンドポイントを使用してコンテナー クラスターを管理する方法を示しています。 +AKS では、Azure に対する責任の多くをオフロードすることによって、Kubernetes クラスターの管理における複雑な運用のオーバーヘッドを削減します。 ホストされている Kubernetes サービスとして、Azure では、正常性の監視や保守などの重要なタスクが処理されます。 また、マスターではなく、クラスター内のエージェント ノードのみの料金を支払います。 マネージド Kubernetes サービスとして、AKS では次が提供されます。 -![](./media/image11-1.png) +- 自動化された Kubernetes バージョンのアップグレードと修正。 +- 簡単なクラスターのスケーリング。 +- 自己復旧のホストされているコントロール プレーン (マスター)。 +- コストの削減 - 実行中のエージェント プール ノードの料金のみを支払う。 -**図 11-1** Docker、Kubernetes、または DC/OS のエンドポイントを使用した Azure Container Service 管理。 +Azure で AKS クラスター内のノードの管理を処理することで、クラスターのアップグレードなど、多くのタスクを手動で実行する必要がなくなりました。 Azure ではこれらの重要な保守タスクが処理されるため、AKS ではクラスターへの直接アクセスを提供しません (SSH の使用など)。 ### Azure Service Fabric @@ -68,24 +67,24 @@ Service Fabric は、新しいアプリを作成している場合や、マイ ### Azure Virtual Machines -既存のアプリケーションで大幅な変更を App Service または Service Fabric で実行する必要がある場合は、クラウドへの移行を簡略化するために Virtual Machines を選択できます。 ただし、Azure App Service および Service Fabric と比較すると、VM の構成、セキュリティ保護、保守を正しく行うには、さらなる時間と IT の専門知識が必要になります。 Azure Virtual Machines を検討している場合は、現在の VM 環境のパッチ適用、更新、管理に必要な、継続的な保守作業を考慮してください。 Azure Virtual Machines はサービスとしてのインフラストラクチャ (IaaS) で、App Service と Service Fabric はサービスとしてのプラットフォーム (PaaS) です。 +既存のアプリケーションで大幅な変更を App Service または Service Fabric で実行する必要がある場合は、クラウドへの移行を簡略化するために Virtual Machines を選択できます。 ただし、Azure App Service および Service Fabric と比較すると、VM の構成、セキュリティ保護、保守を正しく行うには、さらなる時間と IT の専門知識が必要になります。 Azure Virtual Machines を検討している場合は、現在の VM 環境のパッチ適用、更新、管理に必要な、継続的な保守作業を考慮してください。 Azure Virtual Machines はサービスとしてのインフラストラクチャ (IaaS) で、App Service と Service Fabric は PaaS です。 #### 機能の比較 -| 機能 App Service | Service Fabric | 仮想マシン | -|---------|----------|----------| -| ほぼ即時のデプロイ | x | x | | -| 再デプロイせずに大型のマシンにスケールアップ | x | x | | -| インスタンスによるコンテンツと構成の共有。スケーリング時の再デプロイまたは再構成が不要 | x | x | | -| 複数のデプロイ環境 (運用環境、ステージング) | x | x | | -| OS の自動更新の管理 | x | | | -| 32/64 ビットのプラットフォームのシームレスな切り替え | x | | | -| Git、FTP によるコードのデプロイ | x | | x | -| WebDeploy によるコードのデプロイ | x | | x | -| TFS によるコードのデプロイ | x | x | x | -| 多層アーキテクチャの Web または Web サービスのホスティング | x | x | x | -| Service Bus、Storage、SQL Database のような Azure サービスへのアクセス | x | x | x | -| 任意のカスタム MSI のインストール | | x | x | +| 機能 | App Service | コンテナー (AKS) | Service Fabric | 仮想マシン | +| ------------------------------------------------------------------------------------------ | ----------- | ---------------- | -------------- | --------------- | +| ほぼ即時のデプロイ | x | x | x | | +| 再デプロイせずに大型のマシンにスケールアップ | x | x | x | | +| インスタンスによるコンテンツと構成の共有。スケーリング時の再デプロイまたは再構成が不要 | x | x | x | | +| 複数のデプロイ環境 (運用環境、ステージング) | x | x | x | | +| OS の自動更新の管理 | x | x | | | +| 32/64 ビットのプラットフォームのシームレスな切り替え | x | x | | | +| Git、FTP によるコードのデプロイ | x | x | | x | +| WebDeploy によるコードのデプロイ | x | x | | x | +| TFS によるコードのデプロイ | x | x | x | x | +| 多層アーキテクチャの Web または Web サービスのホスティング | x | x | x | x | +| Service Bus、Storage、SQL Database のような Azure サービスへのアクセス | x | x | x | x | +| 任意のカスタム MSI のインストール | | x | x | x | ## 論理プロセス @@ -103,27 +102,30 @@ Azure はさまざまなデータ記憶域のオプションを提供してい ## アーキテクチャに関する推奨事項 -アプリケーションの要件で、アーキテクチャについて指示している必要があります。 使用できる Azure サービスが多いため、正しいサービスを選ぶことが重要です。 Microsoft では、一般的なシナリオに最適化された典型的なアーキテクチャを特定できるように、参照アーキテクチャのギャラリーを提供しています。 アプリケーションの要件に最も近い、または少なくとも使い始めに適している参照アーキテクチャをバインドすることができます。 +アプリケーションの要件で、アーキテクチャについて指示している必要があります。 利用できるさまざまな Azure サービスが多くあります。 適切なサービスを選ぶことが重要です。 Microsoft では、一般的なシナリオに最適化された典型的なアーキテクチャを特定できるように、参照アーキテクチャのギャラリーを提供しています。 アプリケーションの要件に最も近い、または少なくとも使い始めに適している参照アーキテクチャを見つけることができます。 図 11-2 は、参照アーキテクチャの例です。 この図は、マーケティングに最適化された Sitecore コンテンツ管理システム Web サイトに推奨されるアーキテクチャの手法を示しています。 ![](./media/image11-2.png) -**図 11-2** Sitecore マーケティング Web サイトの参照アーキテクチャ。 +**図 11-1** Sitecore マーケティング Web サイトの参照アーキテクチャ。 **参照 – Azure のホスティングの推奨事項** -- Azure ソリューション アーキテクチャ\ - +- Azure ソリューション アーキテクチャ\ + + +- Azure の開発者ガイド\ + -- Azure の開発者ガイド\ - +- Web Apps の概要\ + -- Azure App Service の概要\ - +- Azure App Service、Virtual Machines、Service Fabric および Cloud Services の比較\ + -- Azure App Service、Virtual Machines、Service Fabric および Cloud Services の比較\ - +- Azure Kubernetes Service (AKS) の概要\ + >[!div class="step-by-step"] [前へ](development-process-for-azure.md) diff --git a/docs/standard/modern-web-apps-azure-architecture/choose-between-traditional-web-and-single-page-apps.md b/docs/standard/modern-web-apps-azure-architecture/choose-between-traditional-web-and-single-page-apps.md index 4fd1722e6f9..051a4e024f0 100644 --- a/docs/standard/modern-web-apps-azure-architecture/choose-between-traditional-web-and-single-page-apps.md +++ b/docs/standard/modern-web-apps-azure-architecture/choose-between-traditional-web-and-single-page-apps.md @@ -1,40 +1,38 @@ --- -title: 従来の Web アプリケーションかシングル ページ アプリケーションを選択する -description: ASP.NET Core および Microsoft Azure での最新の Web アプリケーションの設計 -author: ardalis -ms.author: wiwagn -ms.date: 10/06/2017 -ms.openlocfilehash: bbb217b2f11901658fa70a5e5cff6521d157952c -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37104767" +title: 従来の Web アプリケーションかシングル ページ アプリケーションを選択する +description: Web アプリケーションを構築しているときに、従来の Web アプリかシングル ページ アプリケーション (SPA) を選択する方法について説明します。 +author: ardalis +ms.author: wiwagn +ms.date: 6/28/2018 +ms.openlocfilehash: 40b17d07b008c2a3a9457bffc26b612e6b5c9fe5 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404148" --- # 従来の Web アプリケーションかシングル ページ アプリケーション (SPA) を選択する > "Atwood の法則: JavaScript で記述できるすべてのアプリケーションは、最終的に JavaScript で記述される" > _\- Jeff Atwood_ -## まとめ - 現在、Web アプリケーションを構築するには、一般的に 2 つのアプローチがあります。サーバー上でアプリケーション ロジックの大部分を実行する従来の Web アプリケーションと、Web ブラウザーでユーザー インターフェイス ロジックのほとんどを実行し、主に Web API を使用して Web サーバーと通信するシングル ページ アプリケーション (SPA) です。 ハイブリッド アプローチも可能であり、最も単純なのは、高度な SPA のような 1 つ以上のサブアプリケーションを、より大規模な従来の Web アプリケーション内でホストする方法です。 次の場合は、従来の Web アプリケーションを使用することをお勧めします。 -- アプリケーションのクライアント側の要件が単純か、読み取り専用である。 +- アプリケーションのクライアント側の要件が単純か、読み取り専用である。 -- JavaScript をサポートしていないブラウザーでアプリケーションが機能する必要がある。 +- JavaScript をサポートしていないブラウザーでアプリケーションが機能する必要がある。 -- チームが JavaScript や TypeScript の開発手法に精通していない。 +- チームが JavaScript や TypeScript の開発手法に精通していない。 次の場合は、SPA を使用することをお勧めします。 -- アプリケーションで、多くの機能を備えた高度なユーザー インターフェイスを公開する必要がある。 +- アプリケーションで、多くの機能を備えた高度なユーザー インターフェイスを公開する必要がある。 -- チームが JavaScript や TypeScript の開発に精通している。 +- チームが JavaScript や TypeScript の開発に精通している。 -- 他の (内部またはパブリック) クライアントに API を公開するという要件がアプリケーションに既にある。 +- 他の (内部またはパブリック) クライアントに API を公開するという要件がアプリケーションに既にある。 さらに、SPA フレームワークには、より高度なアーキテクチャとセキュリティの専門知識が必要です。 従来の Web アプリケーションよりも頻繁な更新と新しいフレームワークにより、チームは大きな変化を経験します。 SPA アプリケーションでは自動化されたビルドおよび展開プロセスを構成し、コンテナーのような展開オプションを利用するので、従来の Web アプリケーションよりも困難です。 @@ -71,10 +69,11 @@ SPA は、ユーザーが操作を行ったり、アプリケーションの各 SPA を作成するには、JavaScript や TypeScript と、クライアント側のプログラミング手法とライブラリに精通している必要があります。 チームには、Angular のような SPA フレームワークを使用して最新の JavaScript を記述できる能力が必要です。 > ### 参考資料 - SPA フレームワーク +> > - **Angular** -> +> > - **JavaScript フレームワークの比較** -> +> **他の (内部またはパブリック) クライアントに API を公開するという要件がアプリケーションに既にある** @@ -84,12 +83,12 @@ SPA を作成するには、JavaScript や TypeScript と、クライアント 以下の意思決定テーブルは、従来の Web アプリケーションまたは SPA を選択する際に考慮する基本的な要素の一部をまとめたものです。 - | **要素** | **従来の Web アプリケーション** | **シングル ページ アプリケーション** | - |---|---|---| - | チームに必要な JavaScript/TypeScript の精通度 | **最小限** | **必須** | - | スクリプトを作成せずにブラウザーをサポート | **サポート状況** | **サポートされない** | - | 最小限のクライアント側アプリケーションの動作 | **適している** | **過剰** | - | 高度で複雑なユーザー インターフェイス要件 | **制限がある** | **適している** | +| **要素** | **従来の Web アプリケーション** | **シングル ページ アプリケーション** | +| ---------------------------------------------------- | ----------------------- | --------------------------- | +| チームに必要な JavaScript/TypeScript の精通度 | **最小限** | **必須** | +| スクリプトを作成せずにブラウザーをサポート | **サポート状況** | **サポートされない** | +| 最小限のクライアント側アプリケーションの動作 | **適している** | **過剰** | +| 高度で複雑なユーザー インターフェイス要件 | **制限がある** | **適している** | >[!div class="step-by-step"] [前へ](modern-web-applications-characteristics.md) diff --git a/docs/standard/modern-web-apps-azure-architecture/common-client-side-web-technologies.md b/docs/standard/modern-web-apps-azure-architecture/common-client-side-web-technologies.md index 0eb28ba7167..2617af4b0c7 100644 --- a/docs/standard/modern-web-apps-azure-architecture/common-client-side-web-technologies.md +++ b/docs/standard/modern-web-apps-azure-architecture/common-client-side-web-technologies.md @@ -1,23 +1,21 @@ --- -title: 一般的なクライアント側の Web テクノロジ -description: ASP.NET Core および Azure での最新の Web アプリケーションの設計 | 一般的なクライアント側の Web テクノロジ -author: ardalis -ms.author: wiwagn -ms.date: 10/07/2017 -ms.openlocfilehash: 79dac220e40274889783d29c0e04679dd878fda5 -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37106763" +title: 一般的なクライアント側の Web テクノロジ +description: ASP.NET Core および Azure での最新の Web アプリケーションの設計 | 一般的なクライアント側の Web テクノロジ +author: ardalis +ms.author: wiwagn +ms.date: 6/28/2018 +ms.openlocfilehash: 692c1bf243c26ef6dcf441be9324e43d6a93fe50 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404607" --- # 一般的なクライアント側の Web テクノロジ > "Web サイトは中から見ても外から見ても好ましいものでなければならない。" > _- Paul Cookson_ -## まとめ - ASP.NET Core アプリケーションは Web アプリケーションであり、通常、HTML、CSS、JavaScript など、クライアント側の Web テクノロジに依存します。 ページ (HTML) のコンテンツをそのレイアウト、そのスタイル (CSS)、その動作 (JavaScript 経由) から切り離して、複雑な Web アプリでも関心の分離の原則を活用できます。 将来、アプリケーションの構造、設計、動作を変更することになっても、関心が絡み合わなければ簡単に変更できます。 HTML と CSS は比較的安定していますが、Web ベースのアプリケーションを構築する際に開発者が使用するアプリケーション フレームワークであり、ユーティリティである JavaScript は猛烈な速さで進化しています。 この章では、アプリケーションを開発する際に Web 開発者がどのように JavaScript を使用するのかについて説明します。クライアント側のライブラリである Angular と React の概要も説明します。 @@ -38,7 +36,7 @@ CSS (カスケード スタイル シート) は、HTML 要素の外観やレイ ### CSS プリプロセッサ -CSS スタイルシートは、条件付きロジック、変数、その他のプログラミング言語機能に対応していません。 そのため、大きなスタイルシートには多くの場合、たくさんの繰り返しが含まれます。同じ色、フォント、その他の設定がさまざまなバリエーションの HTML 要素と CSS クラスに適用されるためです。 CSS プリプロセッサを利用すると、スタイルシートは変数やロジックに対応し、[DRY 原則](http://deviq.com/don-t-repeat-yourself/)に従うことができます。 +CSS スタイルシートは、条件付きロジック、変数、その他のプログラミング言語機能に対応していません。 そのため、大きなスタイルシートには多くの場合、たくさんの繰り返しが含まれます。同じ色、フォント、その他の設定がさまざまなバリエーションの HTML 要素と CSS クラスに適用されるためです。 CSS プリプロセッサを利用すると、スタイルシートは変数やロジックに対応し、[DRY 原則](https://deviq.com/don-t-repeat-yourself/)に従うことができます。 最も人気のある CSS プリプロセッサは Sass と LESS です。 いずれも CSS を拡張し、CSS との後方互換性があります。つまり、プレーンな CSS ファイルは有効な Sass または LESS ファイルとなります。 Sass は Ruby ベースであり、LESS は JavaScript ベースであり、いずれも通常、ローカル開発プロセスの一部として実行され、 コマンド ライン ツールを利用できます。また、Visual Studio にサポートが組み込まれており、Gulp タスクや Grunt タスクで実行できます。 @@ -48,13 +46,13 @@ JavaScript は解釈型 (コンパイルされず、直接解釈される) の Web アプリケーションで JavaScript を使用するとき、通常実行する必要があるタスクがいくつか存在します。 -- HTML 要素を選択し、その値を取得または更新する +- HTML 要素を選択し、その値を取得したり更新したりする -- Web API にデータを問い合わせる +- Web API にデータを問い合わせる -- Web API にコマンドを送信する (コールバックにその結果で応答する) +- Web API にコマンドを送信する (コールバックにその結果で応答する) -- 検証を実行する +- 検証を実行する これらのタスクをすべて JavaScript のみで実行できますが、タスクを楽にするライブラリがたくさん存在します。 そのようなライブラリで最も人気があるのが jQuery であり、Web ページで上記のタスクを簡単にするライブラリとして選ばれ続けています。 シングルページ アプリケーション (SPA) の場合、求められるさまざまな機能を jQuery は提供しません。Angular と React は提供します。 @@ -100,9 +98,9 @@ export class AppComponent { name = 'Angular'; } DOM 要素の代わりに、コンポーネントとテンプレートを使用して、Angular アプリは高いレベルの抽象化で動作できます。JavaScript ("vanilla JS" とも呼ばれる) や jQuery だけで記述されたアプリより全体的なコードが少なくなります。 Angular にはまた、クライアント側のスクリプト ファイルの整理方法についていくつかの指示があります。 慣例では、Angular アプリは一般的なフォルダー構造を利用します。モジュールとコンポーネントのスクリプト ファイルはアプリ フォルダーに置かれます。 アプリの構築、配置、試験に関連する Angular スクリプトは通常、上位のフォルダーに置かれます。 -Angular ではまた、コマンド ライン インターフェイス (CLI) ツーリングを多用します。 Angular のローカル開発は (git と npm を既にインストールしていると想定します)、GitHub からリポジトリを複製し、\`npm install\` と \`npm start\` を実行するだけで始められます。 それが終わると、Angular から独自の CLI ツールが提供されます。プロジェクトを作成したり、ファイルを追加したり、タスクのテスト、バンドル化、展開に役立てたりできます。 この CLI ツールは使い勝手が良く、Angular と ASP.NET Core の親和性を上げます。ASP.NET Core もまた、CLI のサポート機能に優れています。 +Angular ではまた、コマンド ライン インターフェイス (CLI) ツーリングを多用します。 Angular のローカル開発は (git と npm を既にインストールしていると想定します)、GitHub からリポジトリを複製し、`npm install` と `npm start` を実行するだけで始められます。 それが終わると、Angular から独自の CLI ツールが提供されます。プロジェクトを作成したり、ファイルを追加したり、タスクのテスト、バンドル化、展開に役立てたりできます。 この CLI ツールは使い勝手が良く、Angular と ASP.NET Core の親和性を上げます。ASP.NET Core もまた、CLI のサポート機能に優れています。 -Microsoft は [eShopOnContainers](http://aka.ms/MicroservicesArchitecture) という参照アプリケーションを開発しました。このアプリケーションには、Angular SPA 実装が含まれています。 このアプリには、オンライン ストアの買い物カゴを管理し、そのカタログから品物を読み込んで表示し、注文作成を処理するための Angular モジュールが含まれています。 [GitHub](https://github.com/dotnet-architecture/eShopOnContainers/tree/master/src/Web/WebSPA) でサンプル アプリケーションを表示したり、ダウンロードしたりできます。 +Microsoft は [eShopOnContainers](https://aka.ms/MicroservicesArchitecture) という参照アプリケーションを開発しました。このアプリケーションには、Angular SPA 実装が含まれています。 このアプリには、オンライン ストアの買い物カゴを管理し、そのカタログから品物を読み込んで表示し、注文作成を処理するための Angular モジュールが含まれています。 [GitHub](https://github.com/dotnet-architecture/eShopOnContainers/tree/master/src/Web/WebSPA) でサンプル アプリケーションを表示したり、ダウンロードしたりできます。 ### React @@ -128,17 +126,17 @@ React は完全なフレームワークではないため、通常、ルーテ SPA をサポートする最良の JavaScript フレームワークを求めるとき、次の事項を考慮に入れてください。 -- チームはそのフレームワークとその依存関係に精通しているか (場合によっては TypeScript が含まれます) +- チームはそのフレームワークとその依存関係に精通しているか (場合によっては TypeScript が含まれます) -- そのフレームワークの自己主張性はどの程度か (どのくらい自由度が少ないか)。そのフレームワークの初期設定には同意できるか。 +- そのフレームワークの自己主張性はどの程度か (どのくらい自由度が少ないか)。そのフレームワークの初期設定には同意できるか。 -- そのフレームワーク (またはそれに伴うライブラリ) にアプリで必要とされる機能がすべて含まれているか。 +- そのフレームワーク (またはそれに伴うライブラリ) にアプリで必要とされる機能がすべて含まれているか。 -- 文書は適切に用意されているか。 +- 文書は適切に用意されているか。 -- そのコミュニティはどのくらい活発か。 新しいプロジェクトはそれで構築されているか。 +- そのコミュニティはどのくらい活発か。 新しいプロジェクトはそれで構築されているか。 -- そのコア チームはどのくらい活発か。 問題は解決されているか。新しいバージョンは定期的に出荷されているか。 +- そのコア チームはどのくらい活発か。 問題は解決されているか。新しいバージョンは定期的に出荷されているか。 JavaScript フレームワークは今後も猛烈な速さで進化を続けます。 上記の事項を考慮し、後で後悔するようなフレームワークを選択するリスクを減らしてください。 リスクが特別に好まれない場合、商業的サポートを提供しているフレームワークか大企業が開発しているフレームワークを検討してください。 @@ -168,4 +166,4 @@ JavaScript フレームワークは今後も猛烈な速さで進化を続けま >[!div class="step-by-step"] [前へ](common-web-application-architectures.md) -[次へ](develop-asp-net-core-mvc-apps.md) +[次へ](develop-asp-net-core-mvc-apps.md) \ No newline at end of file diff --git a/docs/standard/modern-web-apps-azure-architecture/common-web-application-architectures.md b/docs/standard/modern-web-apps-azure-architecture/common-web-application-architectures.md index 8a77b480923..1ee11978e4e 100644 --- a/docs/standard/modern-web-apps-azure-architecture/common-web-application-architectures.md +++ b/docs/standard/modern-web-apps-azure-architecture/common-web-application-architectures.md @@ -1,23 +1,21 @@ --- -title: 一般的な Web アプリケーション アーキテクチャ -description: ASP.NET Core および Microsoft Azure での最新の Web アプリケーションの設計 | 一般的な Web アプリケーション アーキテクチャ -author: ardalis -ms.author: wiwagn -ms.date: 10/06/2017 -ms.openlocfilehash: cb9a1d68d4c7c66c6adab3a5e932ee37c3ea22b0 -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37106424" +title: 一般的な Web アプリケーション アーキテクチャ +description: ASP.NET Core および Azure での最新の Web アプリケーションの設計 | 一般的な Web アプリケーション アーキテクチャの探索 +author: ardalis +ms.author: wiwagn +ms.date: 06/28/2018 +ms.openlocfilehash: ff483c9b555fdf394d11626536c28e7e07516d05 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404633" --- # 一般的な Web アプリケーション アーキテクチャ > "優れたアーキテクチャが高価であると思うならば、不完全なアーキテクチャを試してみてください。" > _- Brian Foote および Joseph Yoder_ -## まとめ - 従来の .NET アプリケーションのほとんどは、実行可能ファイルに対応する単一のユニットとして、または 1 つの IIS appdomain 内で実行される単一の Web アプリケーションとして展開されます。 これは最も簡単な展開モデルであり、多くの内部的アプリケーションおよび小さなパブリック アプリケーションに適切に対応します。 ただし、このように単位ユニットとして展開されても、重要なビジネス アプリケーションの大部分は複数のレイヤーへの論理的な分離から恩恵を受けます。 ## モノリシック アプリケーションとは? @@ -30,21 +28,21 @@ ms.locfileid: "37106424" 新しい ASP.NET Core プロジェクトは、Visual Studio またはコマンド ラインのいずれで作成されたかに関係なく、簡単な "オールインワン" モノシリックとして開始されます。 これには、プレゼンテーション、ビジネス、データ アクセス ロジックなど、アプリケーションのあらゆるビヘイビアーが含まれています。 図 5-1 に、単一プロジェクト アプリのファイル構造を示します。 -**図 5-1** 単一プロジェクトの ASP.NET Core アプリ - ![](./media/image5-1.png) +**図 5-1** 単一プロジェクトの ASP.NET Core アプリ。 + 単一プロジェクトのシナリオでは、フォルダーを使用して懸念事項の分離が実現されます。 既定のテンプレートには、Models、Views、および Controllers の MVC パターン責任用の分離フォルダーに加えて、Data および Services 用の追加のフォルダーが含まれています。 この配置では、プレゼンテーションの詳細は可能な限り Views フォルダーに限定する必要があり、データ アクセス実装の詳細は Data フォルダー内に保持されるクラスに限定する必要があります。 ビジネス ロジックは、Models フォルダーにあるサービスとモデル内に配置する必要があります。 -単一プロジェクトのモノリシック ソリューションは簡単なのですが、いくつかの欠点があります。 プロジェクトの規模と複雑さが増大するに従い、ファイルとフォルダーの数も増加し続けます。 アルファベット順にグループ化されていない複数のフォルダーには UI の懸念事項が存在します (Models、Views、Controllers)。 この問題は、Filters や ModelBinders などの UI レベル構造が独自のフォルダーに追加される場合にのみ深刻になります。 ビジネス ロジックは Models フォルダーと Services フォルダーに分散され、どのフォルダーのどのクラスが他のどれに依存すべきかは明示されません。 プロジェクト レベルでのこの編成不足は、[スパゲティ コード](http://deviq.com/spaghetti-code/)の原因となることがよくあります。 +単一プロジェクトのモノリシック ソリューションは簡単なのですが、いくつかの欠点があります。 プロジェクトの規模と複雑さが増大するに従い、ファイルとフォルダーの数も増加し続けます。 アルファベット順にグループ化されていない複数のフォルダーには、ユーザー インターフェイス (UI) の懸念事項 (モデル、ビュー、コントローラー) が存在します。 この問題は、Filters や ModelBinders などの UI レベル構造が独自のフォルダーに追加される場合にのみ深刻になります。 ビジネス ロジックは Models フォルダーと Services フォルダーに分散され、どのフォルダーのどのクラスが他のどれに依存すべきかは明示されません。 プロジェクト レベルでのこの編成不足は、[スパゲティ コード](https://deviq.com/spaghetti-code/)の原因となることがよくあります。 -これらの問題に対処するために、アプリケーションは多くの場合、マルチ プロジェクト ソリューションに展開されます。ここで、各プロジェクトは、アプリケーションの特定の "*レイヤー*" に配置されているとみなされます。 +これらの問題に対処するために、アプリケーションは多くの場合、マルチ プロジェクト ソリューションに展開されます。ここで、各プロジェクトは、アプリケーションの特定の_レイヤー_ に配置されているとみなされます。 ## レイヤーとは? アプリケーションの複雑さが増すにつれて、その複雑さを管理することが必要です。その方法の 1 つが、アプリケーションをその責任や懸念事項に従って分割するというものです。 この方法は懸念事項の分離の原則に従って実施されます。また、この方法を使用すれば、特定の機能が実装されている場所を開発者が容易に見つけられるように、増大するコードベースを常に整理された状態に維持することができます。 ただし、レイヤー化されたアーキテクチャには、単なるコード編成に勝る利点が複数あります。 -コードをレイヤーに編成することにより、よく使われる下位機能をアプリケーション全体で再利用できるようになります。 この再利用を行うと、コードをほとんど記述する必要がなくなり、DRY 原則に従って単一の実装でアプリケーションを標準化できるようになるので、便利です。 +コードをレイヤーに編成することにより、よく使われる下位機能をアプリケーション全体で再利用できるようになります。 この再利用を行うと、コードをほとんど記述する必要がなくなり、[DRY (don't repeat yourself) 原則](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)に従って単一の実装でアプリケーションを標準化できるようになるので、便利です。 レイヤー化されたアーキテクチャの場合、アプリケーションではレイヤー間のやり取りに対して制限を加えることができます。 この制限を利用することで、カプセル化を容易に実現できます。 レイヤーを変更または置換した場合、そのレイヤーと連携しているその他のレイヤーのみが影響を受けます。 レイヤー同士の依存関係を制限することにより、1 つの変更がアプリケーション全体に影響しないように変更の及ぼす影響を軽減することができます。 @@ -55,27 +53,27 @@ ms.locfileid: "37106424" 論理的なレイヤー化は、エンタープライズ ソフトウェア アプリケーションでのコード編成を改善するための一般的な手法です。コードをレイヤーに編成する方法には複数あります。 > [!NOTE] -> "*レイヤー*" とは、アプリケーション内での論理的な分離を表します。 アプリケーション ロジックを個々のサーバーまたはプロセスに物理的に分散するイベントでは、このような個々の物理的展開ターゲットを "*階層*" と呼んでいます。 N レイヤー アプリケーションを単一の階層に展開することは可能であり、これは非常に一般的な方法です。 + > "_レイヤー_" とは、アプリケーション内での論理的な分離を表します。 アプリケーション ロジックを個々のサーバーまたはプロセスに物理的に分散するイベントでは、このような個々の物理的展開ターゲットを "_階層_" と呼んでいます。 N レイヤー アプリケーションを単一の階層に展開することは可能であり、これは非常に一般的な方法です。 ## 従来の "N レイヤー" アーキテクチャ アプリケーション 図 5-2 に、レイヤーへのアプリケーション ロジックの最も一般的な編成を示します。 -**図 5-2** 代表的なアプリケーション レイヤー。 - ![](./media/image5-2.png) +**図 5-2** 代表的なアプリケーション レイヤー。 + これらのレイヤーは多くの場合、UI、BLL (ビジネス ロジック層)、DAL (データ アクセス層) と略称で表現されます。 このアーキテクチャを使用する場合、ユーザーは UI レイヤーを介して要求を行います。UI レイヤーは BLL とのみやり取りします。 次に BLL は、データ アクセス要求のために DAL を呼び出すことができます。 UI レイヤーは DAL に要求を直接出すことも、他の手段によって永続化と直接やり取りすることもありません。 同様に、BLL は DAL を経由して永続化とやり取りするだけです。 この方法では、各レイヤーには独自の既知の責任があります。 この従来のレイヤー化アプローチの欠点の 1 つは、コンパイル時の依存関係が上位から下位に向かって適用されるということです。 つまり、UI レイヤーは BLL に依存し、BLL は DAL に依存するということです。 このことは、アプリケーション内で、通常、最も重要なロジックを保持する BLL が、データ アクセスの実装の詳細 (およびしばしばデータベースの存在) に依存することを意味します。 このようなアーキテクチャでビジネス ロジックをテストするのは困難なことが多く、テスト データベースが必要となります。 次のセクションで示すように、依存関係逆転の原則 (Dependency Inversion principle) を使用すれば、この問題に対処できます。 図 5-3 に、責任 (またはレイヤー) ごとに 3 つのプロジェクトにアプリケーションを分割するソリューションの例を示します。 -**図 5-3** 3 つのプロジェクトによる単純なモノリシック アプリケーション。 - ![](./media/image5-3.png) -このアプリケーションでは編成上の目的で複数のプロジェクトを使用していますが、アプリケーションは引き続き単一ユニットとして展開され、そのクライアントは単一の Web アプリとしてこのアプリケーションとやり取りします。 これにより、展開プロセスが非常に簡単になります。 図 5-4 に、そのようなアプリを Windows Azure を使用してホストする場合の方法を示します。 +**図 5-3** 3 つのプロジェクトによる単純なモノリシック アプリケーション。 + +このアプリケーションでは編成上の目的で複数のプロジェクトを使用していますが、アプリケーションは引き続き単一ユニットとして展開され、そのクライアントは単一の Web アプリとしてこのアプリケーションとやり取りします。 これにより、展開プロセスが非常に簡単になります。 図 5-4 に、そのようなアプリを Azure を使用してホストする場合の方法を示します。 ![](./media/image5-4.png) @@ -99,20 +97,20 @@ Azure 内で Web アプリケーションをスケーリングする最も簡単 ## クリーン アーキテクチャ -依存関係逆転の原則ならびにドメイン駆動設計 (DDD) の原則に従うアプリケーションは、同様のアーキテクチャに到達する傾向があります。 このアーキテクチャには長年にわたってさまざまな名称が付けられてきました。 最初の名前の 1 つがヘキサゴナル アーキテクチャ (Hexagonal Architecture) でした。その後に使用された名前がポート アンド アダプター (Ports-and-Adapters) でした。 最近では、このアーキテクチャは[オニオン アーキテクチャ](http://jeffreypalermo.com/blog/the-onion-architecture-part-1/)または[クリーン アーキテクチャ](https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html)として引用されています。 最も新しい名前が "クリーン アーキテクチャ" です。この電子ブックでは、アーキテクチャの説明で基本的にこの名前が使用されています。 +依存関係逆転の原則ならびにドメイン駆動設計 (DDD) の原則に従うアプリケーションは、同様のアーキテクチャに到達する傾向があります。 このアーキテクチャには長年にわたってさまざまな名称が付けられてきました。 最初の名前の 1 つがヘキサゴナル アーキテクチャ (Hexagonal Architecture) でした。その後に使用された名前がポート アンド アダプター (Ports-and-Adapters) でした。 最近では、このアーキテクチャは[オニオン アーキテクチャ](http://jeffreypalermo.com/blog/the-onion-architecture-part-1/)または[クリーン アーキテクチャ](https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html)として引用されています。 後者のクリーン アーキテクチャは、この電子書籍でアーキテクチャの名前として使用されています。 > [!NOTE] > クリーン アーキテクチャという用語は、DDD 原則を使用して構築されたアプリケーションにも、DDD 原則を使用して構築されていないアプリケーションにも適用できます。 前者の場合、この組み合わせを "クリーン DDD アーキテクチャ" と呼ぶことがあります。 -クリーン アーキテクチャでは、ビジネス ロジックとアプリケーション モデルをアプリケーションの中心に配置します。 ビジネス ロジックはデータ アクセスまたはその他のインフラストラクチャの懸念事項に依存するのでなく、この依存関係は逆転されます。つまり、インフラストラクチャおよび実装の詳細はアプリケーション コアに依存します。 これを達成するには、アプリケーション コア内で抽象化またはインターフェイスを定義し、それらをインフラストラクチャ レイヤーで定義された型によって実装します。 このアーキテクチャを視覚化するための一般的な方法としては、オニオンに似た一連の同心円を使用します。 図 5-X に、このスタイルのアーキテクチャを表現した例を示します。 +クリーン アーキテクチャでは、ビジネス ロジックとアプリケーション モデルをアプリケーションの中心に配置します。 ビジネス ロジックはデータ アクセスまたはその他のインフラストラクチャの懸念事項に依存するのでなく、この依存関係は逆転されます。つまり、インフラストラクチャおよび実装の詳細はアプリケーション コアに依存します。 これを達成するには、アプリケーション コア内で抽象化またはインターフェイスを定義し、それらをインフラストラクチャ レイヤーで定義された型によって実装します。 このアーキテクチャを視覚化するための一般的な方法としては、オニオンに似た一連の同心円を使用します。 図 5-7 に、このスタイルのアーキテクチャを表現した例を示します。 ![](./media/image5-7.png) **図 5-7** クリーン アーキテクチャ。オニオン ビュー -この図では、依存関係が最も内側の円に向かっています。 したがって、アプリケーション コア (この名前は、この図の中心に位置するところから取ったもの) は他のアプリケーション レイヤーに依存していないことがわかります。 真中には、アプリケーションのエンティティとのインターフェイスがあります。 そのすぐ外側 (まだアプリケーション コア内) は、ドメイン サービスです。ここでは通常、内側の円で定義されたインターフェイスを実装します。 アプリケーション コアの外側にはユーザー インターフェイス レイヤーとインフラストラクチャ レイヤーがあります。この 2 つはアプリケーション コアに依存しますが、相互に依存関係があるとは限りません。 +この図では、依存関係が最も内側の円に向かっています。 アプリケーション コアという名前は、この図の中心に位置するところから取ったものです。 この図から、アプリケーション コアが他のアプリケーション レイヤーに依存していないことがわかります。 アプリケーションのエンティティとインターフェイスは真中にあります。 そのすぐ外側 (まだアプリケーション コア内) は、ドメイン サービスです。ここでは通常、内側の円で定義されたインターフェイスを実装します。 アプリケーション コアの外側には、UI レイヤーとインフラストラクチャ レイヤーがあり、これらの両方がアプリケーション コアに依存しますが、相互に依存関係があるとは限りません。 -図 5-X に、UI とその他のレイヤーの間の依存関係をより正確に反映させた、従来の水平方向レイヤー図を示します。 +図 5-8 に、UI とその他のレイヤーの間の依存関係をより正確に反映させた、従来の水平方向レイヤー図を示します。 ![](./media/image5-8.png) @@ -138,9 +136,9 @@ Azure 内で Web アプリケーションをスケーリングする最も簡単 UI レイヤーはインフラストラクチャ プロジェクトで定義された型に対して直接的な依存関係を持たないことから、テストの促進、またはアプリケーション要件の変更への対応を目的として実装を交換することも容易にできます。 ASP.NET Core には依存関係挿入の使用とサポートが組み込まれているので、このアーキテクチャは重要なモノリシック アプリケーションを構築する方法として最適です。 -モノリシック アプリケーションの場合、アプリケーション コア、インフラストラクチャ、ユーザー インターフェイスの各プロジェクトはいずれも単一のアプリケーションとして実行されます。 ランタイム アプリケーションのアーキテクチャは、図 5-12 のようなものになります。 +モノリシック アプリケーションの場合、アプリケーション コア、インフラストラクチャ、UI の各プロジェクトはいずれも単一のアプリケーションとして実行されます。 ランタイム アプリケーションのアーキテクチャは、図 5-12 のようなものになります。 -![ASPNET コア アーキテクチャ 2](./media/image5-12.png) +![ASP.NET Core アーキテクチャ 2](./media/image5-12.png) **図 5-12** ASP.NET Core アプリのランタイム アーキテクチャの例。 @@ -150,36 +148,39 @@ UI レイヤーはインフラストラクチャ プロジェクトで定義さ アプリケーション コアでは、エンティティ、サービス、およびインターフェイスが含まれるビジネス モデルを保持します。 これらのインターフェイスには、データ アクセス、ファイル システム アクセス、ネットワーク呼び出しなどのインフラストラクチャを使用して実行される操作のための抽象化が含まれます。このレイヤーで定義されたサービスまたはインターフェイスは場合によって、UI またはインフラストラクチャに対して依存関係を持たない非エンティティ型を操作する必要があります。 これらは単純なデータ転送オブジェクト (DTO) として定義することができます。 -> ### アプリケーション コアの種類 -> - エンティティ (永続化されたビジネス モデル クラス) -> - インターフェイス -> - Services -> - DTO +### アプリケーション コアの種類 + +- エンティティ (永続化されたビジネス モデル クラス) +- インターフェイス +- Services +- DTO -インフラストラクチャ プロジェクトには、通常、データ アクセス実装が含まれます。 代表的な ASP.NET Core Web アプリケーションでは、これにはエンティティ フレームワーク DbContext、定義済みの任意の EF コア移行、およびデータ アクセス実装クラスが含まれます。 データ アクセス実装コードを抽象化するには、[リポジトリ デザイン パターン](http://deviq.com/repository-pattern/)を使用するのが最も一般的な方法です。 +インフラストラクチャ プロジェクトには、通常、データ アクセス実装が含まれます。 代表的な ASP.NET Core Web アプリケーションの場合、これらの実装には Entity Framework (EF) DbContext、定義済みの任意の EF Core `Migration` オブジェクト、およびデータ アクセス実装クラスが含まれます。 データ アクセス実装コードを抽象化するには、[リポジトリ デザイン パターン](https://deviq.com/repository-pattern/)を使用するのが最も一般的な方法です。 データ アクセス実装に加えて、インフラストラクチャ プロジェクトにはインフラストラクチャの懸念事項とやり取りする必要があるサービスの実装を含める必要があります。 これらのサービスではアプリケーション コアで定義されているインターフェイスを実装する必要があります。そのため、インフラストラクチャにはアプリケーション コア プロジェクトへの参照を含める必要があります。 -> ### インフラストラクチャの種類 -> - EF コア型 (DbContext、移行) -> - データ アクセス実装型 (リポジトリ) -> - インフラストラクチャに固有のサービス (FileLogger、SmtpNotifier など) +### インフラストラクチャの種類 + +- EF Core 型 (`DbContext`、`Migration`) +- データ アクセス実装型 (リポジトリ) +- インフラストラクチャに固有のサービス (`FileLogger` や `SmtpNotifier` など) -ASP.NET Core MVC アプリケーション内のユーザー インターフェイス レイヤーは、アプリケーションのエントリ ポイントになると共に、ASP.NET Core MVC プロジェクトになります。 このプロジェクトはアプリケーション コア プロジェクトを参照する必要があり、その型はアプリケーション コアで定義されているインターフェイスを介してインフラストラクチャと厳密にやり取りする必要があります。 UI レイヤーにおいて、インフラストラクチャ レイヤー型の直接的なインスタンス化 (またはその静的呼び出し) は許可すべきではありません。 +ASP.NET Core MVC アプリケーション内のユーザー インターフェイス レイヤーは、アプリケーションのエントリ ポイントです。 このプロジェクトはアプリケーション コア プロジェクトを参照する必要があり、その型はアプリケーション コアで定義されているインターフェイスを介してインフラストラクチャと厳密にやり取りする必要があります。 UI レイヤーでは、インフラストラクチャ レイヤー型の直接的なインスタンス化や静的呼び出しを許可すべきではありません。 -> ### UI レイヤーの種類 -> - Controllers -> - フィルター -> - Views -> - ViewModels -> - スタートアップ +### UI レイヤーの種類 + +- Controllers +- フィルター +- Views +- ViewModels +- スタートアップ スタートアップ クラスはアプリケーションの構成と、インターフェイスへの実装型の接続とを担当します。これにより、依存関係挿入は実行時に適切に機能します。 > [!NOTE] > UI プロジェクトの Startup.cs ファイル内の ConfigureServices で依存関係挿入を接続するために、プロジェクトはインフラストラクチャ プロジェクトを参照することが必要な場合があります。 この依存関係を排除するには、カスタム DI コンテナーを使用するのが最も簡単な方法です。 このサンプルの目的を考慮すると、UI プロジェクトでインフラストラクチャ プロジェクトを参照できるようにするのが最も簡単な方法です。 -## モノリシック アプリケーションとコンテナー +## モノリシック アプリケーションとコンテナー モノリシックに展開された単一の Web アプリケーションまたはサービスを構築し、それをコンテナーとして展開することができます。 アプリケーション内では、それはモノリシックとはならずにいくつかのライブラリ、コンポーネント、またはレイヤーに編成される場合があります。 外部的には、単一のプロセス、単一の Web アプリケーション、または単一のサービスのような単一のコンテナーです。 @@ -187,15 +188,15 @@ ASP.NET Core MVC アプリケーション内のユーザー インターフェ ![](./media/image5-13.png) -図 5-X に示すように、複数のコンポーネント/ライブラリ、または内部レイヤーを各コンテナーに含めることができます。 ただし、"*コンテナーは 1 つのことを実行し、それを 1 つのプロセスで実行する*" というコンテナーの原則に従えば、このモノリシック パターンは矛盾する可能性があります。 +図 5-13 に示すように、複数のコンポーネント/ライブラリ、または内部レイヤーを各コンテナーに含めることができます。 しかし、"_コンテナーは 1 つのことを実行し、それを 1 つのプロセスで実行する_" というコンテナーの原則に従えば、このモノリシック パターンは矛盾する可能性があります。 このアプローチの欠点は、アプリケーションが大きくなり、スケーリングする必要が出てきた場合に顕著になります。 アプリケーション全体がスケーリングすれば、実際には問題ではありません。 ただし、ほとんどの場合、スケーリングする必要があるネックはアプリケーションの一部であり、他のコンポーネントはそれほど使用されません。 一般的な E コマースを例にとると、スケーリングする必要が生じるのは多くの場合、製品情報のコンポーネントです。 製品を購入するユーザーよりも多くのユーザーが製品を参照します。 より多くの顧客が、支払いパイプラインではなくバスケットを使用します。 コメントを追加したり、購入履歴を表示したりする顧客はそれほどいません。 また、単一のリージョンで、コンテンツとマーケティング キャンペーンを管理する必要がある従業員数は多分、ほんの一握りです。 モノリシック デザインのスケーリングにより、コード全体は複数回展開されます。 -ただし、すべてのコンポーネントをスケーリングする問題に加えて、単一のコンポーネントを変更するには、アプリケーション全体を完全に再テストし、すべてのインスタンスを完全に再展開する必要があります。 +"すべてをスケーリングする" 問題に加えて、単一のコンポーネントを変更するには、アプリケーション全体を完全に再テストし、すべてのインスタンスを完全に再展開する必要があります。 -モノリシック アプローチは一般的であり、多くの組織が、このアーキテクチャ アプローチによって開発を行っています。 多くの組織が十分に良好な結果を収めている一方で、限界に達している組織もあります。 多くの組織は、このモデルでアプリケーションを設計していました。これは、ツールとインフラストラクチャのせいでサービス指向アーキテクチャ (SOA) の構築が非常に困難だったためと、アプリケーションが大きくなるまで SOA の必要性がわからなかったためです。 モノリシック アプローチの限界に達しているとわかった場合は、コンテナーとマイクロサービスを有効活用できるようにアプリに分割することを次の論理的な手順とすることができます。 +モノリシック アプローチは一般的であり、多くの組織が、このアーキテクチャ アプローチによって開発を行っています。 多くの組織が十分に良好な結果を収めている一方で、限界に達している組織もあります。 多くの組織は、このモデルでアプリケーションを設計していました。これは、ツールとインフラストラクチャのせいでサービス指向アーキテクチャ (SOA) の構築が非常に困難だったためと、アプリケーションが大きくなるまで SOA の必要性がわからなかったためです。 モノリシック アプローチの限界に達しているとわかった場合は、コンテナーとマイクロサービスを有効活用できるようにアプリを分割することを次の論理的な手順とすることができます。 ![](./media/image5-14.png) @@ -205,24 +206,114 @@ Microsoft Azure のモノリシック アプリケーションは、各インス ### コンテナーとして展開するモノリシック アプリケーション -コンテナーを使用してモノリシック アプリケーションの展開を管理することには利点があります。 コンテナーのインスタンスをスケーリングする処理は、追加の VM を展開するよりもはるかに高速で簡単です。 VM Scale Sets を使用して VM を拡張する場合も、インスタンス化には時間がかかります。 アプリのインスタンスとして展開する場合、アプリの構成は VM の一部として管理されます。 +コンテナーを使用してモノリシック アプリケーションの展開を管理することには利点があります。 コンテナーのインスタンスをスケーリングする処理は、追加の VM を展開するよりもはるかに高速で簡単です。 仮想マシン スケール セットを使用して VM をスケーリングする場合も、インスタンス化には時間がかかります。 アプリのインスタンスとして展開する場合、アプリの構成は VM の一部として管理されます。 -更新プログラムを Docker イメージとして展開する方がはるかに高速で、ネットワークの効率が高くなります。 通常、Docker イメージは秒単位で起動するので、ロールアウトが高速になります。 Docker インスタンスの破棄は、**docker stop** コマンドの発行と同じくらい簡単で、通常は 1 秒未満で完了します。 +更新プログラムを Docker イメージとして展開する方がはるかに高速で、ネットワークの効率が高くなります。 通常、Docker イメージは秒単位で起動するので、ロールアウトが高速になります。 Docker インスタンスの破棄は、`docker stop` コマンドの発行と同じくらい簡単で、通常は 1 秒未満で完了します。 コンテナーは本質的に設計上、変更不可であるため、VM の破損について心配する必要はありません。一方、更新スクリプトではディスク上に残された特定の構成またはファイルが考慮されない場合があります。 -モノシリック アプリが Docker から恩恵を受けることができる一方で、モノリシック アプリケーションを、スケーリング、開発、および展開を個別に実行できるサブシステムに分割することが、マイクロサービスの領域への入り口になる場合があります。 +_Docker コンテナーは、単純な Web アプリケーションのモノリシックな展開に使用できます。これにより継続的な統合と継続的な展開のパイプラインが向上し、展開から実稼働を成功に導くのために役立ちます。"自分のコンピューターでは動作するのに実稼働環境では動作しないのはなぜ" と悩むことがなくなります。_ + +マイクロサービスベースのアーキテクチャには、多くの利点がありますが、それらの利点のために複雑さが増加します。 場合によっては、コストが利点を上回り、1 つのコンテナーまたは少数のコンテナーで実行されているモノリシック展開アプリケーションの方が有効なことがあります。 + +モノリシック アプリケーションを適切に区切られたマイクロサービスに簡単に分解できない場合があります。 マイクロサービスは相互に独立して起動することで、より回復力のあるアプリケーションを提供します。 アプリケーションの独立した機能のスライスを提供できない場合、分割しても複雑さが増すだけです。 + +場合によっては、アプリケーションを機能に依存せずに拡張できる必要があります 多くのアプリケーションでは、単一のインスタンスの範囲を超えてスケーリングする必要がある場合、そのインスタンス全体を複製する比較的シンプルなプロセスで行うことができます。 アプリケーションを個別のサービスに分割する追加の作業では、アプリケーションのすべてのインスタンスをスケーリングするのがシンプルかつコスト効率に優れている場合、最小限のメリットしか得られません。 + +アプリケーション開発の早い段階では、自然の機能的な境界を明確に把握できないことがあります。 最小の実行可能な製品を開発したときには、自然な境界がまだ明らかにならないことがあります。 これらの条件の一部は、一時的な可能性があります。 最初にモノリシック アプリケーションを作成し、後で一部の個別の機能を開発して、マイクロサービスとして展開する場合があります。 その他の条件はアプリケーションの問題の領域に不可欠な場合があります。つまり、アプリケーションを複数マイクロサービスに分割しない場合があります。 + +多くの個別のプロセスにアプリケーションを分割すると、オーバーヘッドも発生します。 別のプロセスに機能を分離することで、複雑さが増します。 通信プロトコルはより複雑になります。 メソッドの呼び出しではなく、サービス間の非同期通信を使用する必要があります。 マイクロサービス アーキテクチャに移動するきには、eShopOnContainers アプリケーションのマイクロサービス バージョンに実装される多くの構築ブロックを追加する必要があります。つまり、イベント バスの処理、メッセージの回復性と再試行、最終的な整合性などです。 + +よりシンプルな [eShopOnWeb 参照アプリケーション](https://github.com/dotnet-architecture/eShopOnWeb)では、単一コンテナーのモノリシック コンテナーの使用がサポートされます。 アプリケーションには、2 つの Web アプリケーションが含まれています。1 つのアプリケーションでは従来の MVC、もう 1 つでは Razor Pages を使用します。 `docker-compose build` および `docker-compose up` コマンドを使用して、ソリューション ルートからこれらの両方を起動することができます。 このコマンドでは、各 Web プロジェクトのルートで検出された `Dockerfile` を使用して、Web インスタンスごとに個別のコンテナーを構成し、各コンテナーを別のポートで実行します。 GitHub からこのアプリケーションのソースをダウンロードして、ローカルで実行できます。 このモノリシック アプリケーションは、コンテナー環境で展開すると有益です。 + +1 つは、コンテナー化した展開は、アプリケーションのすべてのインスタンスが同じ環境で実行されることを意味します。 これには、初期のテストと開発を行う開発者環境が含まれます。 開発チームは、実稼働環境に一致するコンテナー化した環境でアプリケーションを実行できます。 + +さらに、コンテナー化アプリケーションは低コストでスケールアウトされます。 コンテナー環境を使用することで、従来の VM 環境よりも多くのリソースを共有できます。 + +最後に、アプリケーションのコンテナー化は、強制的にビジネス ロジックと記憶域サーバーの間を分離します。 アプリケーションのスケール アウト時には、複数のコンテナーはすべて単一の物理記憶域メディアに移動します。 通常、この記憶域メディアが SQL Server データベースを実行している高可用性サーバーになります。 + +## Docker のサポート + +`eShopOnWeb` プロジェクトは、.NET Core で実行されます。 そのため、Windows ベースまたは Linux ベースのコンテナーで実行できます。 Docker の展開の場合、SQL Server に同じホストの種類を使用する必要があります。 Linux ベースのコンテナーは、小さなフット プリントが可能なので優先されます。 + +Visual Studio 2017 を使用すれば、Docker サポートを既存のアプリケーションに追加することができます。その場合、**ソリューション エクスプローラー**でプロジェクトを右クリックし、**[追加]** > **[Docker サポート]** の順に選択します。 これで、必要なファイルが追加され、そのファイルを使用するようにプロジェクトが変更されます。 現在の `eShopOnWeb` サンプルには既にこれらのファイルが用意されています。 + +ソリューション レベルの `docker-compose.yml` ファイルには、どのようなイメージをビルドしてどのようなコンテナーを起動するかに関する情報が含まれています。 このファイルでは、`docker-compose` コマンドを使用して、両方のバージョンの Web アプリケーションを同時に起動することができます。 別のデータベース コンテナーなど、依存関係を構成する場合にも使用できます。 + +```yml +version: '3' + +services: + eshopwebrazor: + image: eshopwebrazor + build: + context: . + dockerfile: src/WebRazorPages/Dockerfile + environment: + - ASPNETCORE_ENVIRONMENT=Development + ports: + - "5107:5107" + + eshopwebmvc: + image: eshopwebmvc + build: + context: . + dockerfile: src/Web/Dockerfile + environment: + - ASPNETCORE_ENVIRONMENT=Development + ports: + - "5106:5106" + +networks: + default: + external: + name: nat +``` + +`docker-compose.yml` ファイルでは、`Web` および `WebRazorPages` プロジェクトの `Dockerfile` を参照します。 `Dockerfile` は、使用される基本コンテナーと、その基本コンテナーでのアプリケーションの構成方法を指定する場合に使います。 `WebRazorPages` の `Dockerfile` は次のとおりです。 + +``` +FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base +WORKDIR /app +EXPOSE 80 + +FROM microsoft/aspnetcore-build:2.1.300-preview1 AS build +RUN npm install -g bower@1.8.4 +WORKDIR /src +COPY . . +WORKDIR /src/src/WebRazorPages +RUN dotnet restore -nowarn:msb3202,nu1503 +RUN dotnet build --no-restore -c Release -o /app + +FROM build AS publish +RUN dotnet publish --no-restore -c Release -o /app + +FROM base AS final +WORKDIR /app +COPY --from=publish /app . +ENTRYPOINT ["dotnet", "Microsoft.eShopWeb.RazorPages.dll"] +``` + +### Docker に関する問題のトラブルシューティング + +コンテナー化アプリケーションを実行すると、それを停止するまで実行し続けます。 `docker ps` コマンドで実行されているコンテナーを表示することができます。 `docker stop` コマンドを使用して、コンテナー ID を指定すれば、実行中のコンテナーを停止することができます。 + +実行中の Docker コンテナーは、開発環境では別の目的で使用を試みる可能性のあるポートにバインドされる場合があることに注意してください。 実行中の Docker コンテナーと同じポートを使用して、アプリケーションの実行やデバッグを試みると、サーバーがそのポートにバインドできないことを示すエラーが表示されます。 繰り返しになりますが、コンテナーを停止すると、問題は解決します。 + +Visual Studio を使用して、ご利用のアプリケーションに Docker サポートを追加する場合は、その際に Docker が実行されていることを確認してください。 ウィザードを起動するときに、Docker が実行されていない場合、ウィザードは正しく実行されません。 さらに、ウィザードでは、正しい Docker のサポートを追加するためにコンテナーの現在の選択について説明します。 Windows コンテナーのサポートを追加する場合は、Windows コンテナーが構成された状態で Docker が実行されているときに、ウィザードを実行する必要があります。 Linux コンテナーのサポートを追加する場合は、Linux コンテナーが構成された状態で Docker が実行されているときに、ウィザードを実行する必要があります。 -> ### 参照: 一般的な Web アーキテクチャ +> ### 参照 – 一般的な Web アーキテクチャ +> > - **クリーン アーキテクチャ** -> +> > - **オニオン アーキテクチャ** -> +> > - **リポジトリ パターン** -> +> > - **クリーン アーキテクチャ ソリューションのサンプル** -> -> - **マイクロサービス電子書籍の設計** +> +> - **マイクロサービス電子書籍の設計** +> >[!div class="step-by-step"] [前へ](architectural-principles.md) diff --git a/docs/standard/modern-web-apps-azure-architecture/develop-asp-net-core-mvc-apps.md b/docs/standard/modern-web-apps-azure-architecture/develop-asp-net-core-mvc-apps.md index 9ed2707b904..72e782e1803 100644 --- a/docs/standard/modern-web-apps-azure-architecture/develop-asp-net-core-mvc-apps.md +++ b/docs/standard/modern-web-apps-azure-architecture/develop-asp-net-core-mvc-apps.md @@ -1,30 +1,28 @@ --- -title: ASP.NET Core MVC アプリの開発 -description: ASP.NET Core および Azure での最新の Web アプリケーションの設計 | ASP.NET Core MVC アプリの開発 -author: ardalis -ms.author: wiwagn -ms.date: 10/07/2017 -ms.openlocfilehash: a90f88e117965aec1550a45f114cabfda5204468 -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37106594" +title: ASP.NET Core MVC アプリの開発 +description: ASP.NET Core および Azure での最新の Web アプリケーションの設計 | ASP.NET Core MVC アプリの開発 +author: ardalis +ms.author: wiwagn +ms.date: 06/28/2018 +ms.openlocfilehash: 2fd3eb1e123959130884b96ee9d2e59b83c41b0a +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404646" --- # ASP.NET Core MVC アプリを開発する > "最初から正しく理解する必要はありません。 しかし、最後に正しく理解していることは極めて重要です。" > _- Andrew Hunt、David Thomas_ -## まとめ - ASP.NET Core は、最新のクラウド向けに最適化された Web アプリケーションを構築するための、クロス プラットフォームのオープン ソース フレームワークです。 ASP.NET Core アプリは、軽量なモジュール形式であり、依存関係の挿入の組み込みサポートを備え、テストと保守の容易性を大幅に向上させることができます。 ビュー ベースのアプリだけでなく最新の Web API の構築をサポートする MVC と組み合わせて、ASP.NET Core は、エンタープライズ Web アプリケーション構築のための強力なフレームワークになります。 ## 応答と要求のマッピング -ASP.NET Core アプリの中心となる機能は、受信した要求を送信する応答にマップすることです。 下位のレベルではこれはミドルウェアによって行われ、カスタム ミドルウェアのみで簡単な ASP.NET Core アプリとマイクロサービスを構成することができます。 ASP.NET Core MVC を使うと、"*ルート*"、"*コントローラー*"、"*アクション*" など、さらに上位のレベルで操作することができます。 着信した各要求はアプリケーションのルーティング テーブルと比較され、一致するルートが見つかった場合、関連付けられている (コントローラーに属する) アクション メソッドが呼び出されて要求を処理します。 一致するルートが見つからない場合は、エラー ハンドラーが呼び出されます (この場合、NotFound の結果を返します)。 +ASP.NET Core アプリの中心となる機能は、受信した要求を送信する応答にマップすることです。 下位のレベルではこれはミドルウェアによって行われ、カスタム ミドルウェアのみで簡単な ASP.NET Core アプリとマイクロサービスを構成することができます。 ASP.NET Core MVC を使うと、"_ルート_"、"_コントローラー_"、"_アクション_" など、さらに上位のレベルで操作することができます。 着信した各要求はアプリケーションのルーティング テーブルと比較され、一致するルートが見つかった場合、関連付けられている (コントローラーに属する) アクション メソッドが呼び出されて要求を処理します。 一致するルートが見つからない場合は、エラー ハンドラーが呼び出されます (この場合、NotFound の結果を返します)。 -ASP.NET Core MVC アプリは、規則ルートと属性ルートのどちらか一方または両方を使用できます。 規則ルートはコードで定義されており、次の例のような構文を使ってルーティングの "*規則*" を指定します。 +ASP.NET Core MVC アプリは、規則ルートと属性ルートのどちらか一方または両方を使用できます。 規則ルートはコードで定義されており、次の例のような構文を使ってルーティングの "_規則_" を指定します。 ```csharp app.UseMvc(routes =>; @@ -33,7 +31,7 @@ app.UseMvc(routes =>; }); ``` -この例では、"default" という名前のルートがルーティング テーブルに追加されます。 *controller*、*action*、*id* のプレースホルダーでルート テンプレートを定義します。controller と action プレースホルダーには既定値が指定されており (それぞれ、"Home" と "Index")、id プレースホルダーは ("?" が適用されているので) 省略可能です。 ここで定義されている規則は、要求の最初の部分はコントローラーの名前に対応する必要があり、2 番目の部分はアクションに対応する必要があり、3 番目の部分は必要に応じて id パラメーターを表す、というものです。 規則ルートは通常、Startup クラスの Configure メソッドなど、アプリケーションに対して 1 か所で定義されます。 +この例では、"default" という名前のルートがルーティング テーブルに追加されます。 _controller_、_action_、_id_ のプレースホルダーでルート テンプレートを定義します。controller と action プレースホルダーには既定値が指定されており (それぞれ、"Home" と "Index")、id プレースホルダーは ("?" が適用されているので) 省略可能です。 ここで定義されている規則は、要求の最初の部分はコントローラーの名前に対応する必要があり、2 番目の部分はアクションに対応する必要があり、3 番目の部分は必要に応じて id パラメーターを表す、というものです。 規則ルートは通常、Startup クラスの Configure メソッドなど、アプリケーションに対して 1 か所で定義されます。 属性ルートは、グローバルに指定されるのではなく、コントローラーとアクションに直接適用されます。 この方法の場合、特定のメソッドを探しているときに検出しやすいという利点がありますが、ルーティング情報がアプリケーション内の 1 か所に保持されないことを意味します。 属性ルートでは、特定のアクションに対する複数ルートや、コントローラーとアクションの組み合わせルートを、簡単に指定できます。 例: @@ -45,9 +43,10 @@ public class HomeController : Controller [Route("Index")] // Combines to define route template "Home/Index" [Route("/")] // Does not combine, defines the route template "" public IActionResult Index() {} +} ``` -ルートは [HttpGet] や同様の属性で指定することができ、[Route\] 属性を別途追加する必要はありません。 次に示すように、属性ルートではトークンを使って、コントローラーやアクションの名前を繰り返し指定する必要性を軽減することもできます。 +ルートは [HttpGet] や同様の属性で指定することができ、[Route] 属性を別途追加する必要はありません。 次に示すように、属性ルートではトークンを使って、コントローラーやアクションの名前を繰り返し指定する必要性を軽減することもできます。 ```csharp [Route("[controller\]")] @@ -55,29 +54,32 @@ public class ProductsController : Controller { [Route("")] // Matches 'Products' [Route("Index")] // Matches 'Products/Index' - public IActionResult Index() + public IActionResult Index() {} } ``` -特定の要求がルートと一致した後、アクション メソッドが呼び出される前に、ASP.NET Core MVC は要求に対して[モデル バインド](https://docs.microsoft.com/aspnet/core/mvc/models/model-binding)と[モデル検証](https://docs.microsoft.com/aspnet/core/mvc/models/validation)を実行します。 モデル バインドでは、着信した HTTP データが、呼び出されるアクション メソッドのパラメーターとして指定されている .NET 型に変換されます。 たとえば、アクション メソッドが int 型の ID パラメーターを必要としている場合、モデル バインドは要求の一部として指定された値からこのパラメーターを提供しようとします。 そのために、モデル バインドは、ポストされたフォーム内、ルート自体、クエリ文字列で値を検索します。 ID 値が見つかった場合は、整数に変換されてからアクション メソッドに渡されます。 +特定の要求がルートと一致した後、アクション メソッドが呼び出される前に、ASP.NET Core MVC は要求に対して[モデル バインド](/aspnet/core/mvc/models/model-binding)と[モデル検証](/aspnet/core/mvc/models/validation)を実行します。 モデル バインドでは、着信した HTTP データが、呼び出されるアクション メソッドのパラメーターとして指定されている .NET 型に変換されます。 たとえば、アクション メソッドが int 型の ID パラメーターを必要としている場合、モデル バインドは要求の一部として指定された値からこのパラメーターを提供しようとします。 そのために、モデル バインドは、ポストされたフォーム内、ルート自体、クエリ文字列で値を検索します。 ID 値が見つかった場合は、整数に変換されてからアクション メソッドに渡されます。 モデルをバインドした後、アクション メソッドを呼び出す前に、モデルの検証が行われます。 モデルの検証では、モデルの種類に対するオプション属性が使われ、指定されたモデル オブジェクトが特定のデータ要件に準拠していることを確認できます。 特定の値を必須として指定したり、特定の長さや数値範囲に制限したりすることができます。検証属性が指定されていて、モデルがその要件に準拠していない場合は、ModelState.IsValid プロパティが false に設定され、準拠していない検証規則のセットを要求元のクライアントに送信できます。 -モデルの検証を使う場合は常に、状態変更コマンドを実行する前にモデルが有効であることを確認し、無効なデータによってアプリが破損しないようにする必要があります。 [フィルター](https://docs.microsoft.com/aspnet/core/mvc/controllers/filters)を使って、すべてのアクションにそのためのコードを追加しなくて済むようにできます。 ASP.NET Core MVC フィルターを使うと、要求のグループをインターセプトして、共通のポリシーや横断的な事柄を特定の対象にだけ適用できます。 フィルターは、個々のアクション、コントローラー全体、またはアプリケーション全体に適用できます。 +モデルの検証を使う場合は常に、状態変更コマンドを実行する前にモデルが有効であることを確認し、無効なデータによってアプリが破損しないようにする必要があります。 [フィルター](/aspnet/core/mvc/controllers/filters)を使って、すべてのアクションにそのためのコードを追加しなくて済むようにできます。 ASP.NET Core MVC フィルターを使うと、要求のグループをインターセプトして、共通のポリシーや横断的な事柄を特定の対象にだけ適用できます。 フィルターは、個々のアクション、コントローラー全体、またはアプリケーション全体に適用できます。 -Web API に対しては、ASP.NET Core MVC は[*コンテンツ ネゴシエーション*](https://docs.microsoft.com/aspnet/core/mvc/models/formatting)をサポートしており、応答の書式設定方法を要求で指定することができます。 要求で指定されたヘッダーに基づき、データを返すアクションは、XML、JSON、または他のサポートされている形式で応答を書式設定します。 この機能を使うと、同じ API を、データ形式要件が異なる複数のクライアントで使用できます。 +Web API に対しては、ASP.NET Core MVC は[_コンテンツ ネゴシエーション_](/aspnet/core/mvc/models/formatting)をサポートしており、応答の書式設定方法を要求で指定することができます。 要求で指定されたヘッダーに基づき、データを返すアクションは、XML、JSON、または他のサポートされている形式で応答を書式設定します。 この機能を使うと、同じ API を、データ形式要件が異なる複数のクライアントで使用できます。 > ### 参照 – 応答と要求のマッピング +> > - **コントローラー アクションへのルーティング** > -> - **モデル バインド** https://docs.microsoft.com/aspnet/core/mvc/models/model-binding +> - **モデル バインド** +> > - **モデルの検証** > -> - **フィルター** https://docs.microsoft.com/aspnet/core/mvc/controllers/filters +> - **フィルター** +> ## 依存関係の使用 -ASP.NET Core は、[依存関係の挿入](https://docs.microsoft.com/aspnet/core/fundamentals/dependency-injection)と呼ばれる手法の組み込みサポートを備えており、内部的に使用します。 依存関係の挿入は、アプリケーションの異なる部分間を疎結合できる手法です。 結合を緩くすることを、アプリケーションの各部分の分離が容易になり、部分ごとにテストや置換が可能になるため、望ましいことです。 また、アプリケーションの 1 つの部分に対する変更が、アプリケーションの別の場所に予期しない影響を与える可能性も低くなります。 依存関係の挿入は、依存関係逆転 (Dependency Inversion) の原則に基づいており、多くの場合、開放/閉鎖 (Open/closed) の原則の実現に不可欠です。 アプリケーションによる依存関係の処理方法を評価するときは、[静的な結び付き](http://deviq.com/static-cling/)を持つコードのにおいに注意し、"[new は接着剤である](https://ardalis.com/new-is-glue)" という格言を思い出してください。 +ASP.NET Core は、[依存関係の挿入](/aspnet/core/fundamentals/dependency-injection)と呼ばれる手法の組み込みサポートを備えており、内部的に使用します。 依存関係の挿入は、アプリケーションの異なる部分間を疎結合できる手法です。 結合を緩くすることを、アプリケーションの各部分の分離が容易になり、部分ごとにテストや置換が可能になるため、望ましいことです。 また、アプリケーションの 1 つの部分に対する変更が、アプリケーションの別の場所に予期しない影響を与える可能性も低くなります。 依存関係の挿入は、依存関係逆転 (Dependency Inversion) の原則に基づいており、多くの場合、開放/閉鎖 (Open/closed) の原則の実現に不可欠です。 アプリケーションによる依存関係の処理方法を評価するときは、[静的な結び付き](https://deviq.com/static-cling/)を持つコードのにおいに注意し、"[new は接着剤である](https://ardalis.com/new-is-glue)" という格言を思い出してください。 静的な結び付きは、クラスが静的メソッドを呼び出したとき、または静的プロパティにアクセスしたときに発生し、インフラストラクチャに対する副作用または依存関係があります。 たとえば、あるメソッドが静的メソッドを呼び出し、その静的メソッドがデータベースに書き込む場合、元のメソッドはデータベースに密に結合されます。 何かによってデータベース呼び出しが中断されると、メソッドも中断されます。 このようなメソッドのテストは、静的な呼び出しを模倣するために市販のモック ライブラリが必要になるか、またはテスト データベースを使ってしかテストできないため、非常に困難です。 インフラストラクチャに対する依存関係のない静的呼び出しは (特に、完全にステートレスのもの)、問題なく呼び出すことができて、結合や (コードの結合だけでなく静的な呼び出し自体の) テスト可能性に影響を与えません。 @@ -118,7 +120,7 @@ public void Configure(IApplicationBuilder app, > [!NOTE] > 特定のサービスを Startup クラスで確実に利用できるようにする必要がある場合は、WebHostBuilder とその ConfigureServices メソッドを使ってサービスを構成できます。 -Startup クラスは、独自のサービスに対するコントローラーからミドルウェアやフィルターまで、ASP.NET Core アプリケーションの他の部分で必要な構成方法のモデルになります。 いずれの場合も、[明示的な依存関係の原則](http://deviq.com/explicit-dependencies-principle/)に従い、依存関係を直接作成するのではなく要求し、アプリケーション全体で依存関係の挿入を利用する必要があります。 実装を直接インスタンス化する場所と方法に注意する必要があります (特に、インフラストラクチャを使用する、または副作用があるサービスとオブジェクトの場合)。 特定の実装の種類に対する参照をハードコーディングするのではなく、抽象化をアプリケーション コアで定義し、引数として渡すようにします。 +Startup クラスは、独自のサービスに対するコントローラーからミドルウェアやフィルターまで、ASP.NET Core アプリケーションの他の部分で必要な構成方法のモデルになります。 いずれの場合も、[明示的な依存関係の原則](https://deviq.com/explicit-dependencies-principle/)に従い、依存関係を直接作成するのではなく要求し、アプリケーション全体で依存関係の挿入を利用する必要があります。 実装を直接インスタンス化する場所と方法に注意する必要があります (特に、インフラストラクチャを使用する、または副作用があるサービスとオブジェクトの場合)。 特定の実装の種類に対する参照をハードコーディングするのではなく、抽象化をアプリケーション コアで定義し、引数として渡すようにします。 ## アプリケーションの構成 @@ -136,7 +138,7 @@ ASP.NET Core UI プロジェクトは、UI レベルの処理を行いますが ### 機能の編成 -既定では、ASP.NET Core アプリケーションは、コントローラーとビューさらに多くの場合は ViewModels を含むように、フォルダー構造を編成します。 通常、これらのサーバー側構造をサポートするためのクライアント側のコードは、wwwroot フォルダーに個別に格納されます。 ただし、大規模なアプリケーションでは、特定の機能を使用するためにこれらのフォルダー間を移動する必要があるため、このような編成では問題が発生する可能性があります。 各フォルダー内のファイルとサブフォルダーの数が増えるとますます困難になり、ソリューション エクスプローラーのスクロール量が膨大になります。 この問題の 1 つの解決策は、アプリケーションのコードをファイルの種類別ではなく "*機能*" 別に整理することです。 この編成スタイルは、通常、機能フォルダーまたは機能スライスと呼ばれます ([垂直スライス](http://deviq.com/vertical-slices/)も参照してください)。 +既定では、ASP.NET Core アプリケーションは、コントローラーとビューさらに多くの場合は ViewModels を含むように、フォルダー構造を編成します。 通常、これらのサーバー側構造をサポートするためのクライアント側のコードは、wwwroot フォルダーに個別に格納されます。 ただし、大規模なアプリケーションでは、特定の機能を使用するためにこれらのフォルダー間を移動する必要があるため、このような編成では問題が発生する可能性があります。 各フォルダー内のファイルとサブフォルダーの数が増えるとますます困難になり、ソリューション エクスプローラーのスクロール量が膨大になります。 この問題の 1 つの解決策は、アプリケーションのコードをファイルの種類別ではなく "_機能_" 別に整理することです。 この編成スタイルは、通常、機能フォルダーまたは機能スライスと呼ばれます ([垂直スライス](https://deviq.com/vertical-slices/)も参照してください)。 ASP.NET Core MVC では、この目的のために区分 (Area) がサポートされています。 区分を使うと、各区分フォルダー内にコントローラー フォルダーとビュー フォルダー (および関連するすべてのモデル) のセットを個別に作成できます。 図 7-1 は、区分を使用したフォルダー構造の例です。 @@ -205,7 +207,7 @@ services.AddMvc(o => o.Conventions.Add(new FeatureConvention())); ### 横断的な問題 -アプリケーションが大きくなるほど、横断的な事柄を抽出して、重複を排除し、整合性を維持することの重要性が増します。 ASP.NET Core アプリケーションでの横断的な事柄の例としては、認証、モデル検証規則、出力キャッシュ、エラー処理などがありますが、その他にも多くのことがあります。 ASP.NET Core MVC で[フィルター](https://docs.microsoft.com/aspnet/core/mvc/controllers/filters)を使うと、要求処理パイプラインの特定のステップの前または後にコードを実行できます。 たとえば、フィルターは、モデル バインドの前後、アクションの前後、またはアクションの結果の前後に実行できます。 また、承認フィルターを使って、パイプラインの残りの部分へのアクセスを制御することができます。 図 7-2 では、フィルターを構成した場合に要求の実行がそれをどのように通過するかを示します。 +アプリケーションが大きくなるほど、横断的な事柄を抽出して、重複を排除し、整合性を維持することの重要性が増します。 ASP.NET Core アプリケーションでの横断的な事柄の例としては、認証、モデル検証規則、出力キャッシュ、エラー処理などがありますが、その他にも多くのことがあります。 ASP.NET Core MVC で[フィルター](/aspnet/core/mvc/controllers/filters)を使うと、要求処理パイプラインの特定のステップの前または後にコードを実行できます。 たとえば、フィルターは、モデル バインドの前後、アクションの前後、またはアクションの結果の前後に実行できます。 また、承認フィルターを使って、パイプラインの残りの部分へのアクセスを制御することができます。 図 7-2 では、フィルターを構成した場合に要求の実行がそれをどのように通過するかを示します。 ![要求は、承認フィルター、リソース フィルター、モデル バインド、アクション フィルター、アクションの実行とアクション結果の変換、例外フィルター、結果フィルター、結果の実行を介して処理されます。 終了間際に、要求は結果フィルターとリソース フィルターのみで処理されてから、クライアントに送信される応答になります。](./media/image7-2.png) @@ -264,7 +266,6 @@ public class ValidateModelAttribute : ActionFilterAttribute 同様に、フィルターを使ってレコードが存在するかどうかをチェックし、アクションが実行される前に 404 を返して、アクションでこれらのチェックを実行する必要がないようにできます。 共通の規則を抽出し、インフラストラクチャ コードとビジネス ロジックを UI から分離するようにソリューションを構成すると、MVC アクション メソッドは非常にスリムになるはずです。 ```csharp -// PUT api/authors/2/5 [HttpPut("{id}")] [ValidateAuthorExists] public async Task Put(int id, [FromBody]Author author) @@ -276,19 +277,20 @@ public async Task Put(int id, [FromBody]Author author) フィルターの実装について詳しくは、MSDN の記事「[実際の ASP.NET Core MVC フィルター](https://msdn.microsoft.com/magazine/mt767699.aspx)」をご覧ください。動作するサンプルをダウンロードすることもできます。 -> ### 参照: アプリケーションの構成 +> ### 参照 – アプリケーションの構成 +> > - **領域** -> -> - **MSDN - ASP.NET Core MVC 向け機能スライス** -> +> +> - **MSDN マガジン - ASP.NET Core MVC 向け機能スライス** + > > - **フィルター** -> +> > - **MSDN – 実際の ASP.NET Core MVC フィルター** -> +> ## セキュリティ -Web アプリケーションのセキュリティ保護は大きなトピックであり、さまざまな考慮事項があります。 最も基本的なレベルのセキュリティには、特定の要求を行ったユーザーを認識し、その要求が必要なリソースだけにアクセスできるようにすることが含まれます。 認証は、要求で提供された資格情報を、信頼できるデータ ストア内の資格情報と比較して、要求を既知のエンティティから送信されたものとして扱う必要があるかどうかを確認するプロセスです。 承認は、ユーザーの ID に基づいて特定のリソースへのアクセスを制限するプロセスです。 セキュリティに関する 3 番目の考慮事項は、第三者による傍受から要求を保護することであり、少なくとも[アプリケーションが SSL を使っていることを確認する](https://docs.microsoft.com/aspnet/core/security/enforcing-ssl)必要があります。 +Web アプリケーションのセキュリティ保護は大きなトピックであり、さまざまな考慮事項があります。 最も基本的なレベルのセキュリティには、特定の要求を行ったユーザーを認識し、その要求が必要なリソースだけにアクセスできるようにすることが含まれます。 認証は、要求で提供された資格情報を、信頼できるデータ ストア内の資格情報と比較して、要求を既知のエンティティから送信されたものとして扱う必要があるかどうかを確認するプロセスです。 承認は、ユーザーの ID に基づいて特定のリソースへのアクセスを制限するプロセスです。 セキュリティに関する 3 番目の考慮事項は、第三者による傍受から要求を保護することであり、少なくとも[アプリケーションが SSL を使っていることを確認する](/aspnet/core/security/enforcing-ssl)必要があります。 ### 認証 @@ -329,7 +331,7 @@ public void Configure(IApplicationBuilder app) Configure メソッドで UseMvc の前に UseIdentity を指定することが重要です。 ConfigureServices で Identity を構成すると、AddDefaultTokenProviders の呼び出しがあることがわかります。 これは、Web 通信をセキュリティ保護するために使われる場合があるトークンとは関係なく、ユーザーによる ID 確認のために SMS またはメールでユーザーに送信できるプロンプトを作成するプロバイダーを参照しています。 -詳しくは、ASP.NET Core の公式ドキュメントで [2 要素認証の構成](https://docs.microsoft.com/aspnet/core/security/authentication/2fa)および[外部ログイン プロバイダーの有効化](https://docs.microsoft.com/aspnet/core/security/authentication/social/)に関する記事をご覧ください。 +詳しくは、ASP.NET Core の公式ドキュメントで [2 要素認証の構成](/aspnet/core/security/authentication/2fa)および[外部ログイン プロバイダーの有効化](/aspnet/core/security/authentication/social/)に関する記事をご覧ください。 ### 承認 @@ -383,40 +385,41 @@ public void ConfigureServices(IServiceCollection services) **図 7-4.** Web API に対するトークン ベースの認証。 > ### 参照 – セキュリティ +> > - **セキュリティ ドキュメントの概要** -> https://docs.microsoft.com/aspnet/core/security/ +> https://docs.microsoft.com/aspnet/core/security/ > - **ASP.NET Core アプリで SSL を適用する** -> +> > - **Identity の概要** -> +> > - **承認の概要** -> +> > - **Azure App Service での API Apps に対する認証および承認** -> +> ## クライアントの通信 Web API によりページを提供してデータの要求に応答するだけでなく、ASP.NET Core アプリは接続されているクライアントと直接通信できます。 この送信通信では、さまざまなトランスポート テクノロジを使うことができ、最も一般的なものは WebSocket です。 ASP.NET Core SignalR は、サーバーとクライアントの間のリアルタイム通信機能をアプリケーションに容易に追加できるようにするライブラリです。 SignalR は、WebSocket などのさまざまなトランスポート テクノロジをサポートしており、多くの実装の詳細を開発者から抽象化します。 -ASP.NET Core SignalR は現在開発中であり、ASP.NET Core の次のリリースで提供されます。 ただし、他の[オープン ソースの WebSocket ライブラリ](https://github.com/radu-matei/websocket-manager)は現在でも使用できます。 +ASP.NET Core SignalR は ASP.NET Core 2.1 で使用できます。 WebSocket を直接使うか、他の技法を使うかに関係なく、リアルタイムのクライアント通信は、さまざまなアプリケーション シナリオで役に立ちます。 次に、それらの例の一部を示します。 -- ライブ チャット ルーム アプリケーション +- ライブ チャット ルーム アプリケーション -- アプリケーションの監視 +- アプリケーションの監視 -- ジョブの進行状況の更新 +- ジョブの進行状況の更新 -- 通知 +- 通知 -- 対話型のフォーム アプリケーション +- 対話型のフォーム アプリケーション クライアント通信をアプリケーションに組み込むときは、通常、2 つのコンポーネントがあります。 -- サーバー側の接続マネージャー (SignalR Hub、WebSocketManager WebSocketHandler) +- サーバー側の接続マネージャー (SignalR Hub、WebSocketManager WebSocketHandler) -- クライアント側のライブラリ +- クライアント側のライブラリ クライアントはブラウザーに限定されず、モバイル アプリ、コンソール アプリ、他のネイティブ アプリも SignalR/WebSocket を使って通信できます。 次の簡単なプログラムは、WebSocketManager サンプル アプリケーションの一部として、チャット アプリケーションに送信されたすべての内容をコンソールにエコーします。 @@ -434,58 +437,60 @@ public class Program Console.ReadLine(); StopConnectionAsync(); } - + public static async Task StartConnectionAsync() { _connection = new Connection(); await _connection.StartConnectionAsync("ws://localhost:65110/chat"); } - + public static async Task StopConnectionAsync() { await _connection.StopConnectionAsync(); } +} ``` アプリケーションがクライアント アプリケーションと直接通信する方法を検討し、リアルタイム通信によってアプリのユーザー エクスペリエンスが向上するかどうかを検討します。 > ### 参照 – クライアントの通信 +> > - **ASP.NET Core SignalR** -> +> > - **WebSocket マネージャー** -> https://github.com/radu-matei/websocket-manager +> https://github.com/radu-matei/websocket-manager ## ドメイン駆動設計 – 適用する必要があるか? -ドメイン駆動設計 (DDD) は、"*ビジネス ドメイン*" に注目するソフトウェア構築のためのアジャイルな方法です。 実際のシステムのしくみについて開発者に関わることができるビジネス ドメインの専門家とのコミュニケーションと対話に重点が置かれます。 たとえば、株取引を処理するシステムを構築する場合のドメインの専門家は、経験豊富な株式ブローカーなどです。 DDD は、大規模で複雑なビジネスの問題に対処するように設計されており、多くの場合、ドメインの理解とモデリングに対する投資に見合わないため、小さくて単純なアプリケーションには適しません。 +ドメイン駆動設計 (DDD) は、"_ビジネス ドメイン_" に注目するソフトウェア構築のためのアジャイルな方法です。 実際のシステムのしくみについて開発者に関わることができるビジネス ドメインの専門家とのコミュニケーションと対話に重点が置かれます。 たとえば、株取引を処理するシステムを構築する場合のドメインの専門家は、経験豊富な株式ブローカーなどです。 DDD は、大規模で複雑なビジネスの問題に対処するように設計されており、多くの場合、ドメインの理解とモデリングに対する投資に見合わないため、小さくて単純なアプリケーションには適しません。 -DDD 手法でソフトウェアを作成する場合、チーム (非技術的な利害関係者や貢献者を含む) は問題領域のための "*ユビキタス言語*" を開発する必要があります。 つまり、モデル化される実際の概念、それに相当するソフトウェア、概念を保持するために存在する構造 (データベース テーブルなど) に、同じ用語を使う必要があります。 したがって、ユビキタス言語で説明される概念は、"*ドメイン モデル*" の基礎を形成する必要があります。 +DDD 手法でソフトウェアを作成する場合、チーム (非技術的な利害関係者や貢献者を含む) は問題領域のための "_ユビキタス言語_" を開発する必要があります。 つまり、モデル化される実際の概念、それに相当するソフトウェア、概念を保持するために存在する構造 (データベース テーブルなど) に、同じ用語を使う必要があります。 したがって、ユビキタス言語で説明される概念は、"_ドメイン モデル_" の基礎を形成する必要があります。 ドメイン モデルは、相互に対話してシステムの動作を表すオブジェクトで構成されます。 これらのオブジェクトは以下のカテゴリに分けられます。 -- [エンティティ](http://deviq.com/entity/)は、ID のスレッドでオブジェクトを表します。 エンティティは、通常、後で取得できるキーを使って永続的に格納されます。 +- [エンティティ](https://deviq.com/entity/)は、ID のスレッドでオブジェクトを表します。 エンティティは、通常、後で取得できるキーを使って永続的に格納されます。 -- [集計](http://deviq.com/aggregate-pattern/)は、単位として永続化する必要のあるオブジェクトのグループを表します。 +- [集計](https://deviq.com/aggregate-pattern/)は、単位として永続化する必要のあるオブジェクトのグループを表します。 -- [値オブジェクト](http://deviq.com/value-object/)は、プロパティ値の合計に基づいて比較できる概念を表します。 たとえば、開始日と終了日で構成される DateRange などです。 +- [値オブジェクト](https://deviq.com/value-object/)は、プロパティ値の合計に基づいて比較できる概念を表します。 たとえば、開始日と終了日で構成される DateRange などです。 -- [ドメイン イベント](https://martinfowler.com/eaaDev/DomainEvent.html)は、システムの他の部分にとって重要な、システム内で発生している出来事を表します。 +- [ドメイン イベント](https://martinfowler.com/eaaDev/DomainEvent.html)は、システムの他の部分にとって重要な、システム内で発生している出来事を表します。 -DDD ドメイン モデルでは、モデル内に複雑な動作をカプセル化する必要があることに注意してください。 特にエンティティは、プロパティの単なるコレクションであってはなりません。 ドメイン モデルに動作が欠如していて、システムの状態を表しているだけの場合は、[貧血症のモデル](http://deviq.com/anemic-model/)と呼ばれ、DDD では望ましくないことです。 +DDD ドメイン モデルでは、モデル内に複雑な動作をカプセル化する必要があることに注意してください。 特にエンティティは、プロパティの単なるコレクションであってはなりません。 ドメイン モデルに動作が欠如していて、システムの状態を表しているだけの場合は、[貧血症のモデル](https://deviq.com/anemic-model/)と呼ばれ、DDD では望ましくないことです。 これらのモデルの種類に加えて、通常、DDD ではさまざまなパターンが使用されます。 -- [リポジトリ](http://deviq.com/repository-pattern/)は、永続化の詳細を抽象化します。 +- [リポジトリ](https://deviq.com/repository-pattern/)は、永続化の詳細を抽象化します。 -- [ファクトリ](https://en.wikipedia.org/wiki/Factory_method_pattern)は、複雑なオブジェクトの作成をカプセル化します。 +- [ファクトリ](https://en.wikipedia.org/wiki/Factory_method_pattern)は、複雑なオブジェクトの作成をカプセル化します。 -- ドメイン イベントは、トリガーの動作から依存する動作を分離します。 +- ドメイン イベントは、トリガーの動作から依存する動作を分離します。 -- [サービス](http://gorodinski.com/blog/2012/04/14/services-in-domain-driven-design-ddd/)は、複雑な動作やインフラストラクチャの実装の詳細をカプセル化します。 +- [サービス](http://gorodinski.com/blog/2012/04/14/services-in-domain-driven-design-ddd/)は、複雑な動作やインフラストラクチャの実装の詳細をカプセル化します。 -- [コマンド](https://en.wikipedia.org/wiki/Command_pattern)は、コマンドの発行とコマンド自体の実行を切り離します。 +- [コマンド](https://en.wikipedia.org/wiki/Command_pattern)は、コマンドの発行とコマンド自体の実行を切り離します。 -- [仕様](http://deviq.com/specification-pattern/)は、クエリの詳細をカプセル化します。 +- [仕様](https://deviq.com/specification-pattern/)は、クエリの詳細をカプセル化します。 また、DDD では、疎結合、カプセル化、単体テストを使って簡単に検証できるコードに対応するため、前に説明したクリーン アーキテクチャを使うことも推奨されます。 @@ -500,8 +505,9 @@ DDD では、モデリング、アーキテクチャ、コミュニケーショ ハイブリッド アプローチでは、アプリケーションのトランザクション部分やさらに複雑な部分にだけ DDD を使い、アプリケーションの簡単な CRUD 部分や読み取り専用の部分には使わないようにします。 たとえば、レポートを表示したり、ダッシュボードにデータを視覚化したりするためにデータをクエリする場合、集計の制約を使用する必要はありません。 このような要件に対しては、独立したシンプルな読み取りモデルでまったく問題ありません。 > ### 参照 – ドメイン駆動設計 +> > - **わかりやすい英語での DDD (StackOverflow の回答)** -> +> ## 配置 @@ -525,31 +531,32 @@ Kestrel Web サーバーでホストされる ASP.NET Core アプリケーショ Azure でアプリケーションをホストしている場合は、専用の仮想アプライアンスとして Microsoft Azure Application Gateway を使って、複数のサービスを提供できます。 個々のアプリケーションに対するリバース プロキシとして動作するだけでなく、Application Gateway は次の機能を提供することもできます。 -- HTTP の負荷分散 +- HTTP の負荷分散 -- SSL のオフロード (インターネットに対する SSL のみ) +- SSL のオフロード (インターネットに対する SSL のみ) -- エンド ツー エンドの SSL +- エンド ツー エンドの SSL -- 複数サイトのルーティング (最大 20 個のサイトを 1 つの Application Gateway に統合) +- 複数サイトのルーティング (最大 20 個のサイトを 1 つの Application Gateway に統合) -- Web アプリケーション ファイアウォール +- Web アプリケーション ファイアウォール -- WebSocket のサポート +- WebSocket のサポート -- 高度な診断 +- 高度な診断 -*Azure の展開オプションについては 10 章で説明します。* +_Azure のデプロイ オプションについては、[10 章](development-process-for-azure.md)で説明します。_ > ### 参照 – 展開 +> > - **ホスティングと展開の概要** -> +> > - **Kestrel とリバース プロキシを使用するタイミング** -> +> > - **Docker で ASP.NET Core アプリをホストする** -> +> > - **Azure Application Gateway の概要** -> +> >[!div class="step-by-step"] [前へ](common-client-side-web-technologies.md) diff --git a/docs/standard/modern-web-apps-azure-architecture/development-process-for-azure.md b/docs/standard/modern-web-apps-azure-architecture/development-process-for-azure.md index 69efdf4d346..933347db070 100644 --- a/docs/standard/modern-web-apps-azure-architecture/development-process-for-azure.md +++ b/docs/standard/modern-web-apps-azure-architecture/development-process-for-azure.md @@ -1,15 +1,15 @@ --- -title: Azure の開発プロセス -description: ASP.NET Core および Azure での最新の Web アプリケーションの設計 | Azure の開発プロセス -author: ardalis -ms.author: wiwagn -ms.date: 10/08/2017 -ms.openlocfilehash: ea7b173369cea3b785297a136546d65965c3d789 -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37106854" +title: Azure の開発プロセス +description: ASP.NET Core および Azure での最新の Web アプリケーションの設計 | Azure の開発プロセス +author: ardalis +ms.author: wiwagn +ms.date: 06/28/2018 +ms.openlocfilehash: bde771051af034e7da72e9648fb3b0f37a95fa01 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404390" --- # Azure の開発プロセス @@ -40,8 +40,6 @@ ms.locfileid: "37106854" [Visual Studio Code をダウンロードする](https://code.visualstudio.com/download) - - ## Azure でホストされる ASP.NET Core アプリの開発ワークフロー アプリケーション開発のライフサイクルは、各開発者のコンピューターで開始されます。その場合、アプリは開発者の好みの言語でコーディングされ、ローカルでテストされます。 開発者は好みのソース管理システムを選択できます。また、ビルド サーバーを使用するか、組み込みの Azure 機能に基づいて、継続的インテグレーション (CI) および/または継続的デリバリー/デプロイ (CD) を構成できます。 @@ -52,9 +50,9 @@ CI/CD を使用して ASP.NET Core アプリケーションの開発を開始す アプリのリリース パイプラインを作成するには、ソース管理でアプリケーション コードを使用する必要があります。 ローカル リポジトリをセットアップし、それをチーム プロジェクトのリモート リポジトリに接続します。 次の手順に従ってください。 -- [Git と Visual Studio でコードを共有する](https://docs.microsoft.com/vsts/git/share-your-code-in-git-vs)、または +- [Git と Visual Studio でコードを共有する](https://docs.microsoft.com/vsts/git/share-your-code-in-git-vs)、または -- [TFVC と Visual Studio でコードを共有する](https://docs.microsoft.com/vsts/tfvc/share-your-code-in-tfvc-vs) +- [TFVC と Visual Studio でコードを共有する](https://docs.microsoft.com/vsts/tfvc/share-your-code-in-tfvc-vs) アプリケーションをデプロイする Azure App Service を作成します。 Azure Portal の App Services ブレードに移動して、Web アプリを作成します。 [+追加] をクリックして Web アプリ テンプレートを選択し、[作成] をクリックして名前とその他の詳細を入力します。 Web アプリは {name}.azurewebsites.net からアクセス可能になります。 @@ -98,7 +96,7 @@ Azure にデプロイする場合の ASP.NET Core アプリケーションの開 ビルドが成功すると、CD プロセスは生成されたビルド成果物を選択します。 これには、Web デプロイ パッケージが含まれます。 ビルド サーバーは Azure App Service にこのパッケージをデプロイして、既存のサービスを新しく作成されたものに置き換えます。 通常、この手順の対象はステージング環境ですが、一部のアプリケーションは CD プロセスを通じて運用環境に直接デプロイします。 -#### 手順 5. Azure App Service。 Web アプリ。 +#### 手順 5. Azure App Service Web アプリ デプロイ後、ASP.NET Core アプリケーションは Azure App Service Web アプリのコンテキスト内で実行されます。 この Web アプリは、Azure Portal を使用して監視でき、さらに構成することができます。 @@ -111,7 +109,6 @@ Web アプリの実行中に、アプリケーションの正常性を監視し **ASP.NET Core アプリを構築して Azure にデプロイする** - >[!div class="step-by-step"] [前へ](test-asp-net-core-mvc-apps.md) -[次へ](azure-hosting-recommendations-for-asp-net-web-apps.md) +[次へ](azure-hosting-recommendations-for-asp-net-web-apps.md) \ No newline at end of file diff --git a/docs/standard/modern-web-apps-azure-architecture/modern-web-applications-characteristics.md b/docs/standard/modern-web-apps-azure-architecture/modern-web-applications-characteristics.md index 8342ce7f5bd..a3c22176ab6 100644 --- a/docs/standard/modern-web-apps-azure-architecture/modern-web-applications-characteristics.md +++ b/docs/standard/modern-web-apps-azure-architecture/modern-web-applications-characteristics.md @@ -1,38 +1,37 @@ --- -title: 最新の Web アプリケーションの特徴 -description: ASP.NET Core と Azure を使用した最新の Web アプリケーションの設計 | 最新の Web アプリケーションの特徴 -author: ardalis -ms.author: wiwagn -ms.date: 10/06/2017 -ms.openlocfilehash: cc4493bf8e45c41a94e8e6f719318b14ad5b05f1 -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37105808" +title: 最新の Web アプリケーションの特徴 +description: ASP.NET Core と Azure を使用した最新の Web アプリケーションの設計 | 最新の Web アプリケーションの特徴 +author: ardalis +ms.author: wiwagn +ms.date: 06/28/2018 +ms.openlocfilehash: 4c73ab59148325f66d3ee17db3fb78d397b73f15 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404487" --- # 最新の Web アプリケーションの特徴 > "… 設計が適切であれば、低コストで機能を提供できます。 このアプローチは困難ですが、成功は継続します」 > _\- Dennis Ritchie_ -## まとめ - 最新の Web アプリケーションに対するユーザーの期待と要求は、これまでよりも高くなります。 現代の Web アプリケーションは、世界中どこからでも 24 時間 365 日いつでも利用でき、ほぼあらゆるデバイスや画面サイズから使用できることが期待されます。 Web アプリケーションは、需要の急増に対応するために、セキュリティで保護され、柔軟性が高く、スケーラブルである必要があります。 ますます複雑になっているシナリオに対して、JavaScript を使用し、Web API を介して効率的に通信する高度なユーザー エクスペリエンスをクライアント上に構築して対処する必要があります。 ASP.NET Core は、最新の Web アプリケーションとクラウドベースのホスティング シナリオに合わせて最適化されています。 モジュール式の設計なので、アプリケーションは実際に使用する機能のみに依存することができます。さらに、アプリケーションのセキュリティとパフォーマンスが向上し、ホスティングのリソース要件は軽減されます。 ## 参照アプリケーション: eShopOnWeb -このガイダンスには、いくつかの原則と推奨事項を示す参照アプリケーション *eShopOnWeb* が含まれています。 このアプリケーションは単純なオンライン ストアです。シャツ、コーヒー マグなどの商品のカタログを閲覧することができます。 この参照アプリケーションは、わかりやすくするために意図的に単純にしています。 +このガイダンスには、いくつかの原則と推奨事項を示す参照アプリケーション _eShopOnWeb_ が含まれています。 このアプリケーションは単純なオンライン ストアです。シャツ、コーヒー マグなどの商品のカタログを閲覧することができます。 この参照アプリケーションは、わかりやすくするために意図的に単純にしています。 **図 2-1** eShopOnWeb ![](./media/image2-1.png) > ### 参照アプリケーション +> > - **eShopOnWeb** -> +> ## クラウドでのホストとスケーラビリティ @@ -58,7 +57,7 @@ ASP.NET Core アプリケーションは単体テストをサポートしてい これに対し、シングル ページ アプリケーション (SPA) の場合は、動的に生成されるサーバー側のページ読み込み (存在する場合) はほとんどありません。 多くの SPA は、アプリケーションを起動して実行するために必要な JavaScript ライブラリを読み込む静的 HTML ファイル内で初期化されます。 このようなアプリケーションはデータのニーズに合わせて Web API を多用し、より高度なユーザー エクスペリエンスを提供できます。 -多くの Web アプリケーションでは、従来の Web アプリケーションの動作 (通常はコンテンツ用) と SPA (対話機能用) を組み合わせています。 ASP.NET Core は、同じアプリケーション内で同じツール セットと基礎のフレームワーク ライブラリを使用して MVC と Web API の両方をサポートしています。 +多くの Web アプリケーションでは、従来の Web アプリケーションの動作 (通常はコンテンツ用) と SPA (対話機能用) を組み合わせています。 ASP.NET Core は、同じアプリケーション内で同じツール セットと基礎のフレームワーク ライブラリを使用して MVC (ビューや Razor Pages) と Web API の両方をサポートしています。 ## 単純な開発と展開 @@ -69,12 +68,13 @@ ASP.NET Core アプリケーションは、単純なテキスト エディター ASP.NET Core だけでなく、従来の ASP.NET 4.x も、Web アプリケーションの構築に適した堅牢で信頼性の高いプラットフォームです。 ASP.NET は MVC および Web API 開発モデルと Web フォームをサポートしており、高度なページ ベースのアプリケーション開発に適しています。また、豊富なサード パーティのコンポーネント エコシステムを備えています。 Windows Azure は ASP.NET 4.x アプリケーションを長年にわたってサポートしているので、多くの開発者はこのプラットフォームに精通しています。 > ### 参照 – 最新の Web アプリケーション +> > - **ASP.NET Core の概要** -> +> > - **ASP.NET Core が優れていることを示す 6 つの主な利点** -> +> > - **ASP.NET Core でのテスト** -> +> >[!div class="step-by-step"] [前へ](index.md) diff --git a/docs/standard/modern-web-apps-azure-architecture/test-asp-net-core-mvc-apps.md b/docs/standard/modern-web-apps-azure-architecture/test-asp-net-core-mvc-apps.md index c3f273af785..aa327f2f45c 100644 --- a/docs/standard/modern-web-apps-azure-architecture/test-asp-net-core-mvc-apps.md +++ b/docs/standard/modern-web-apps-azure-architecture/test-asp-net-core-mvc-apps.md @@ -1,22 +1,20 @@ --- -title: ASP.NET Core MVC アプリのテスト -description: ASP.NET Core および Azure での最新の Web アプリケーションの設計 | ASP.NET Core MVC アプリのテスト -author: ardalis -ms.author: wiwagn -ms.date: 10/08/2017 -ms.openlocfilehash: b22e0e109144b4abd04cd4199cfdec244d8fa7af -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37106503" +title: ASP.NET Core MVC アプリのテスト +description: ASP.NET Core および Azure での最新の Web アプリケーションの設計 | ASP.NET Core MVC アプリのテスト +author: ardalis +ms.author: wiwagn +ms.date: 06/28/2018 +ms.openlocfilehash: b6c881a445f5848829ab5ccc6ce8547a390d89f3 +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404620" --- # ASP.NET Core MVC アプリのテスト -> _"あなたが製品の単体テストを好まないと、あなたの顧客もテストを望まないでしょう。"_ -> _- 作者不明 -_ - -## まとめ +> *"あなたが製品の単体テストを好まないと、あなたの顧客もテストを望まないでしょう。"* + > \_- 匿名 - 変更に対応するとき、複雑なソフトウェアには予想外のエラーが発生することがあります。 そのため、ほとんどの些細な (少なくとも重要性が最も低い) アプリケーションを除くすべてのアプリケーションで変更後のテストが必須となります。 手動テストはソフトウェアのテスト方法として最も遅く、信頼性がなく、高額です。 残念ながら、アプリケーションにテスト機能が付いていない場合、手動テストが唯一の手段になることがあります。 第 X 章に記載されているアーキテクチャ原則に基づいてアプリケーションが記述されている場合、単体テスト可能になるはずです。ASP.NET Core アプリケーションは、自動化統合と機能テストにも対応しています。 @@ -68,7 +66,7 @@ public class LocalFileImageService : IImageService > "多くの場合、システムの開発は家の建築に例えられます。 この類推はまったく正しいというわけではありませんが、単体テストと機能テストの違いを理解する目的で拡大解釈できます。 単体テストは、建築調査官が家の建築現場を訪問する行為に似ています。 調査官は家のさまざまな内部システム、土台、骨組み、電気、配管を重点的に調べ、 家の各部分が正しく安全に機能すること、つまり、建築法規に準拠していることを確認 (テスト) します。 このシナリオにおける機能テストは、家主がこの同じ建築現場を訪問する行為に似ています。 家主は、内部システムが適切に動作し、建築調査官がその仕事を遂行しているものと想定し、 その家で生活することはどのような感じになるのかを重点的に確認します。 家はどのように見えるか、各部屋の大きさはちょうど良いか、家は家族の希望に合っているか、朝日を取り入れる場所に窓が取り付けられているかが重要となります。 家主は家に機能テストを実行します。 家主の視点はユーザーの視点です。 建築調査官は家に単体テストを実行します。 調査官の視点は開発者の視点です。" -出典: [Unit Testing versus Functional Tests](http://www.softwaretestingtricks.com/2007/01/unit-testing-versus-functional-tests.html) (単体テストと機能テストの比較) +出典: [Unit Testing versus Functional Tests](https://www.softwaretestingtricks.com/2007/01/unit-testing-versus-functional-tests.html) (単体テストと機能テストの比較) "開発者は 2 通りの失敗をします。間違った方法で開発することと間違ったものを開発することです。" というのは私の好きな表現です。 単体テストでは、正しい方法で開発していることを確認します。機能テストでは、正しいものを開発していることを確認します。 @@ -84,7 +82,7 @@ Martin Fowler がテストをピラミッド図にしました。図 9-1 がそ ピラミッドの各層はテストの種類を表し、その相対的な大きさはアプリケーションのために記述すべきテストの数を表します。 ご覧のように、単体テストの土台を大きくし、それより小さい統合テスト層が続き、さらに小さい機能テスト層が続くという構成が推奨されています。 各層には、理想的には、それより下の層では適切に実行できないテストのみを含めます。 特定のシナリオで必要とするテストの種類を決定するとき、このピラミッドを念頭に置いてください。 -### テストの内容。 +### テストの内容 自動化テストの記述経験がない開発者にとっては、何をテストするのかが共通の問題です。 理想的な出発点は条件ロジックをテストすることです。 条件文 (if-else、switch など) に基づいて変化する動作を持つメソッドが含まれる箇所で少なくとも 2、3 のテストが思い付くはずです。特定の条件に対して正しい動作を確認するテストです。 コードの条件に間違いがある場合、(エラーのない) コード経由で "Happy Path" のテストを少なくとも 1 つ記述し、(エラーがあるか、結果が不規則な) "Sad Path" のテストを少なくとも 1 つ記述し、エラーに直面したときにアプリケーションが予想どおりに動作することを確認することをお勧めします。 最後に、コード カバレッジなどの指標ではなく、エラーが起こりうるものに対するテストに集中的に取り組みます。 一般的に、カバレッジは少ないよりも多い方が良いとされます。 しかしながら、非常に複雑でビジネスクリティカルなメソッドのテストを 2、3 多く記述することは、テストのコード カバレッジ指標を改善するためだけに自動プロパティのテストを記述することより、通常、時間の使い方として優れています。 @@ -108,19 +106,19 @@ Martin Fowler がテストをピラミッド図にしました。図 9-1 がそ テストには一貫性のある名前を付けてください。それぞれのテストの内容を示す名前にします。 テストするクラスやメソッドに基づいてテスト クラスに名前を付けるという方法でうまく行ったことがあります。 結果的に小さなテスト クラスがたくさん作られますが、それぞれのテストが担当する内容は極めて明白になります。 テストするクラスやメソッドを識別するためにテスト クラスの名前を設定したら、テスト メソッド名を利用し、テストする動作を指定できます。 それにより、求められる動作と、その動作を生むための入力や前提が含まれます。 テスト名の例: -- CatalogControllerGetImage.CallsImageServiceWithId +- `CatalogControllerGetImage.CallsImageServiceWithId` -- CatalogControllerGetImage.LogsWarningGivenImageMissingException +- `CatalogControllerGetImage.LogsWarningGivenImageMissingException` -- CatalogControllerGetImage.ReturnsFileResultWithBytesGivenSuccess +- `CatalogControllerGetImage.ReturnsFileResultWithBytesGivenSuccess` -- CatalogControllerGetImage.ReturnsNotFoundResultGivenImageMissingException +- `CatalogControllerGetImage.ReturnsNotFoundResultGivenImageMissingException` この方法のバリエーションとしては、それぞれのテスト クラスの名前の末尾を "Should" にして時制を少し変えます。 -- CatalogControllerGetImage**Should**.**Call**ImageServiceWithId +- `CatalogControllerGetImage`**Should**`.`**Call**`ImageServiceWithId` -- CatalogControllerGetImage**Should**.**Log**WarningGivenImageMissingException +- `CatalogControllerGetImage`**Should**`.`**Log**`WarningGivenImageMissingException` 少しばかり冗長ですが、2 つ目の命名規則の方がわかりやすいと感じるチームもあるでしょう。 いずれにせよ、テストの動作がわかる命名規則を利用してください。テストが失敗したとき、何が失敗したのか名前から判断できます。 ControllerTests.Test1 のような曖昧な名前をテストに付けないでください。テスト結果に表示されたとき、何の有用性もありません。 @@ -175,9 +173,7 @@ public IActionResult GetImage(int id) ## ASP.NET Core Apps を統合テストする -このサービスでは、別個のサービスに改良される前の CatalogController コードと同様に、IHostingEnvironment が使用されます。 これがコントローラーで IHostingEnvironment を使用した唯一のコードであったため、その依存関係は CatalogController のコンストラクターから削除されました。 - -このサービスが正しく機能することをテストするには、既知のテスト画像ファイルを作成し、特定の入力後、サービスがそのファイルを正しく返すことを検証する必要があります。 実際にテストする動作 (この場合、ファイル システムから読み込むこと) にはモック オブジェクトを使用しないでください。 ただし、統合テストの設定でもモック オブジェクトは役に立ちます。 この事例では、その ContentRootPath がテスト画像に使用するフォルダーを指すように IHostingEnvironment をモックできます。 完璧に動作する統合テスト クラスは次のようになります。 +統合テストを使用して LocalFileImageService が正しく機能することをテストするには、既知のテスト画像ファイルを作成し、特定の入力後、サービスがそのファイルを正しく返すことを検証する必要があります。 実際にテストする動作 (この場合、ファイル システムから読み込むこと) にはモック オブジェクトを使用しないでください。 ただし、統合テストの設定でもモック オブジェクトは役に立ちます。 この事例では、その ContentRootPath がテスト画像に使用するフォルダーを指すように IHostingEnvironment をモックできます。 完璧に動作する統合テスト クラスは次のようになります。 ```csharp public class LocalFileImageServiceGetImageBytesById @@ -186,6 +182,7 @@ public class LocalFileImageServiceGetImageBytesById private readonly Mock _mockEnvironment = new Mock(); private int _testImageId = 123; private string _testFileName = "123.png"; + public LocalFileImageServiceGetImageBytesById() { // create folder if necessary @@ -194,24 +191,25 @@ public class LocalFileImageServiceGetImageBytesById System.IO.File.WriteAllBytes(filePath, _testBytes); _mockEnvironment.SetupGet(m => m.ContentRootPath).Returns(GetFileDirectory()); } + private string GetFilePath(string fileName) { return Path.Combine(GetFileDirectory(), "Pics", fileName); } private string GetFileDirectory() { - var location = System.Reflection.Assembly.GetEntryAssembly().Location; - return Path.GetDirectoryName(location); - } + var location = System.Reflection.Assembly.GetEntryAssembly().Location; + return Path.GetDirectoryName(location); + } - [Fact] - public void ReturnsFileContentResultGivenValidId() - { - var fileService = new LocalFileImageService(_mockEnvironment.Object); - var result = fileService.GetImageBytesById(_testImageId); - Assert.Equal(_testBytes, result); - } + [Fact] + public void ReturnsFileContentResultGivenValidId() + { + var fileService = new LocalFileImageService(_mockEnvironment.Object); + var result = fileService.GetImageBytesById(_testImageId); + Assert.Equal(_testBytes, result); } +} ``` > [!NOTE] @@ -219,58 +217,134 @@ public class LocalFileImageServiceGetImageBytesById ## ASP.NET Core アプリを機能テストする -ASP.NET Core アプリケーションの場合、TestServer クラスを利用すると、機能テストをとても簡単に記述できます。 アプリケーションに普通に行うように、WebHostBuilder を利用して TestServer を構成します。 この WebHostBuilder はアプリケーションの実際のホストと同じように構成すべきですが、テストが楽にするあらゆる側面を改良できます。 ほとんどの場合、さまざまなテスト ケースで同じ TestServer を再利用します。再利用可能メソッドでカプセル化できます (おそらく基底クラスで)。 +ASP.NET Core アプリケーションの場合、TestServer クラスを利用すると、機能テストをとても簡単に記述できます。 (通常、自分のアプリケーションで使用するように) WebHostBuilder を直接使用するか、WebApplicationFactory 型 (2.1 で利用可能) で、TestServer を構成します。 テスト ホストと運用ホストをできる限り一致させるようにする必要があるため、テストではアプリが運用環境で実行する内容と同様の動作が実行されます。 WebApplicationFactory クラスは、ビューなどの静的リソースを検索するために ASP.NET Core によって使用される、TestServer の ContentRoot を構成するときに便利です。 -```csharp -public abstract class BaseWebTest +TEntry が Web アプリケーションの Startup クラスである、IClassFixture> を実装するテスト クラスを作成することによって、単純な機能テストを作成できます。 これを配置すると、ファクトリの CreateClient メソッドを使用して、テスト フィクスチャでクライアントを作成できます。 + +```cs +public class BasicWebTests : IClassFixture> { protected readonly HttpClient _client; - protected string _contentRoot; - public BaseWebTest() + public BaseWebTest(WebApplicationFactory factory) { - _client = GetClient(); + _client = factory.CreateClient(); } - protected HttpClient GetClient() + // write tests that use _client +} +``` + +アプリケーションをメモリ データ ストアで使用するように構成し、テスト データを使ってアプリケーションをシードするなど、各テストを実行する前に、ご利用のサイトの追加の構成を実行する必要があることがよくあります。 これを行うには、独自の WebApplicationFactory のサブクラスを作成して、その ConfigureWebHost メソッドをオーバーライドする必要があります。 以下の例は、eShopOnWeb FunctionalTests プロジェクトからのもので、メインの Web アプリケーション上でのテストの一部として使用されます。 + +```cs +using Infrastructure.Data; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.eShopWeb; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using System; +using Microsoft.EntityFrameworkCore; +using Infrastructure.Identity; + +namespace FunctionalTests.WebRazorPages +{ + public class CustomWebRazorPagesApplicationFactory + : WebApplicationFactory { - var startupAssembly = typeof(Startup).GetTypeInfo().Assembly; - _contentRoot = GetProjectPath("src", startupAssembly); - var builder = new WebHostBuilder() - .UseContentRoot(_contentRoot) - .UseStartup(); - var server = new TestServer(builder); - var client = server.CreateClient(); - return client; + protected override void ConfigureWebHost(IWebHostBuilder builder) + { + builder.ConfigureServices(services => + { + // Create a new service provider. + var serviceProvider = new ServiceCollection() + .AddEntityFrameworkInMemoryDatabase() + .BuildServiceProvider(); + + // Add a database context (ApplicationDbContext) using an in-memory + // database for testing. + services.AddDbContext(options => + { + options.UseInMemoryDatabase("InMemoryDbForTesting"); + options.UseInternalServiceProvider(serviceProvider); + }); + + services.AddDbContext(options => + { + options.UseInMemoryDatabase("Identity"); + options.UseInternalServiceProvider(serviceProvider); + }); + + // Build the service provider. + var sp = services.BuildServiceProvider(); + + // Create a scope to obtain a reference to the database + // context (ApplicationDbContext). + using (var scope = sp.CreateScope()) + { + var scopedServices = scope.ServiceProvider; + var db = scopedServices.GetRequiredService(); + var loggerFactory = scopedServices.GetRequiredService(); + + var logger = scopedServices + .GetRequiredService>>(); + + // Ensure the database is created. + db.Database.EnsureCreated(); + + try + { + // Seed the database with test data. + CatalogContextSeed.SeedAsync(db, loggerFactory).Wait(); + } + catch (Exception ex) + { + logger.LogError(ex, $"An error occurred seeding the " + + "database with test messages. Error: {ex.Message}"); + } + } + }); + } } } ``` -GetProjectPath メソッドは、Web プロジェクトの物理パスを返します (サンプル ソリューションをダウンロードする)。 この場合の WebHostBuilder は Web アプリケーションのコンテンツ ルートがある場所を指定し、実際の Web アプリケーションが使用する同じ Startup クラスを参照します。 TestServer と連動させるには、標準の System.Net.HttpClient 型を利用し、TestServer に要求します。 TestServer は便利な CreateClient メソッドを公開します。このメソッドが提供する事前構成済みのクライアントは、TestServer で実行されているアプリケーションにいつでも要求を出せます。 ASP.NET Core アプリケーションのために機能テストを記述するとき、このクライアントを使用します (上記の基本テストで保護 \_client メンバーに設定されています)。 +テストでは、クライアントを作成するために使用し、このクライアント インスタンスを使用してアプリケーションに要求を出すことによって、このカスタム WebApplicationFactory を活用できます。 アプリケーションには、テストのアサーションの一部として使用できる、シードされたデータがあります。 このテストは、eShopOnWeb Razor Pages アプリケーションのホーム ページが正しく読み込まれることを検証し、シード データの一部としてアプリケーションに追加された製品の一覧が含まれます。 -```csharp -public class CatalogControllerGetImage : BaseWebTest +```cs +using Microsoft.eShopWeb.RazorPages; +using System.Net.Http; +using System.Threading.Tasks; +using Xunit; + +namespace FunctionalTests.WebRazorPages { - [Fact] - public async Task ReturnsFileContentResultGivenValidId() + public class HomePageOnGet : IClassFixture> { - var testFilePath = Path.Combine(_contentRoot, "pics//1.png"); - var expectedFileBytes = File.ReadAllBytes(testFilePath); - var response = await _client.GetAsync("/catalog/pic/1"); - response.EnsureSuccessStatusCode(); - var streamResponse = await response.Content.ReadAsStreamAsync(); - byte[] byteResult; - using (var ms = new MemoryStream()) + public HomePageOnGet(CustomWebRazorPagesApplicationFactory factory) { - streamResponse.CopyTo(ms); - byteResult = ms.ToArray(); + Client = factory.CreateClient(); + } + + public HttpClient Client { get; } + + [Fact] + public async Task ReturnsHomePageWithProductListing() + { + // Arrange & Act + var response = await Client.GetAsync("/"); + response.EnsureSuccessStatusCode(); + var stringResponse = await response.Content.ReadAsStringAsync(); + + // Assert + Assert.Contains(".NET Bot Black Sweatshirt", stringResponse); // from seed data } - Assert.Equal(expectedFileBytes, byteResult); } } ``` -この機能テストは、配置されているあらゆるミドルウェア、フィルター、バインダーなど、完全な ASP.NET Core MVC アプリケーション スタックを行使します。 既知の場所にあるファイルに対して予想されるバイト配列を所与のルート ("/catalog/pic/1") が返すことを検証します。 これは実際の Web サーバーを設定せずに行い、実際の Web サーバーを利用して不安定になることを回避します (ファイアウォール設定の問題など)。 TestServer に対して実行される機能テストは通常、統合テストや単体テストより遅くなりますが、テスト Web サーバーのネットワークで実行されるテストよりはるかに速くなります。 +この機能テストは、配置されているあらゆるミドルウェア、フィルター、バインダーなど、完全な ASP.NET Core MVC / Razor Pages アプリケーション スタックを行使します。 特定のルート ("/") が想定される正常な状態コードと HTML 出力を返すことを検証します。 これは実際の Web サーバーを設定せずに行い、実際の Web サーバーを利用して不安定になることを回避します (ファイアウォール設定の問題など)。 TestServer に対して実行される機能テストは通常、統合テストや単体テストより遅くなりますが、テスト Web サーバーのネットワークで実行されるテストよりはるかに速くなります。 機能テストを使用して、アプリケーションのフロント エンドのスタックが想定どおりに動作していることを確認する必要があります。 これらのテストは、コントローラーやページに重複があり、フィルターを追加して重複に対処するときに特に便利です。 このリファクタリングではアプリケーションの動作を変更せずに、機能テストのスイートによってこの状況を検証することをお勧めします。 >[!div class="step-by-step"] [前へ](work-with-data-in-asp-net-core-apps.md) diff --git a/docs/standard/modern-web-apps-azure-architecture/work-with-data-in-asp-net-core-apps.md b/docs/standard/modern-web-apps-azure-architecture/work-with-data-in-asp-net-core-apps.md index 3038b31e6fe..b3c92f9e323 100644 --- a/docs/standard/modern-web-apps-azure-architecture/work-with-data-in-asp-net-core-apps.md +++ b/docs/standard/modern-web-apps-azure-architecture/work-with-data-in-asp-net-core-apps.md @@ -1,23 +1,21 @@ --- -title: ASP.NET Core アプリでのデータの操作 -description: ASP.NET Core および Azure での最新の Web アプリケーションの設計 | asp でのデータの操作 -author: ardalis -ms.author: wiwagn -ms.date: 10/07/2017 -ms.openlocfilehash: c9f1350f57ed649b9bf53968c19ab652b3c74384 -ms.sourcegitcommit: 979597cd8055534b63d2c6ee8322938a27d0c87b -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 06/29/2018 -ms.locfileid: "37106176" +title: ASP.NET Core アプリでのデータの操作 +description: ASP.NET Core および Azure での最新の Web アプリケーションの設計 | ASP.NET Core アプリでのデータの操作 +author: ardalis +ms.author: wiwagn +ms.date: 06/28/2018 +ms.openlocfilehash: 7209789eb36dc717823625c0ae67357ee332086b +ms.sourcegitcommit: 4c158beee818c408d45a9609bfc06f209a523e22 +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/03/2018 +ms.locfileid: "37404659" --- # ASP.NET Core アプリでのデータの操作 > "データは貴重なものであり、システム自体よりも長く存在します。" - -Tim Berners-lee - -## まとめ +> +> Tim Berners-lee データ アクセスは、ほぼすべてのソフトウェア アプリケーションの重要な部分です。 ASP.NET Core は、Entity Framework Core (および Entity Framework 6 も) を含む、さまざまなデータ アクセス オプションをサポートし、どの .NET データ アクセス フレームワークでも使用できます。 使用するデータ アクセス フレームワークの選択は、アプリケーションのニーズによって異なります。 ApplicationCore および UI プロジェクトからのこれらの選択を抽象化し、インフラストラクチャに実装の詳細をカプセル化することは、疎結合のテスト可能なソフトウェアの生成に役立ちます。 @@ -35,7 +33,7 @@ dotnet add package Microsoft.EntityFrameworkCore.InMemory ### DbContext -EF Core を操作するには、DbContext のサブクラスが必要です。 このクラスでは、ご利用のアプリケーションで操作するエンティティのコレクションを表すプロパティを保持します。 eShopOnWeb サンプルには、アイテム、ブランド、型のコレクションと共に CatalogContext が含まれます。 +EF Core を操作するには、 のサブクラスが必要です。 このクラスでは、ご利用のアプリケーションで操作するエンティティのコレクションを表すプロパティを保持します。 eShopOnWeb サンプルには、アイテム、ブランド、型のコレクションと共に CatalogContext が含まれます。 ```csharp public class CatalogContext : DbContext @@ -116,7 +114,7 @@ EF Core では、フェッチおよび保存のための同期と非同期の両 ### 関連データのフェッチ -EF Core は、エンティティの取得時に、データベースのそのエンティティを直接格納されているすべてのプロパティに設定します。 関連エンティティのリストなどの、ナビゲーション プロパティは設定されず、その値が null に設定される場合があります。 これにより、EF Core は必要以上のデータをフェッチしなくなります。これは、効率的な方法ですばやく要求を処理し、応答を返す必要がある、Web アプリケーションの場合に特に重要です。 *一括読み込み*を使用して、エンティティとのリレーションシップを含めるには、次のように、クエリで Include 拡張メソッドを使用してプロパティを指定します。 +EF Core は、エンティティの取得時に、データベースのそのエンティティを直接格納されているすべてのプロパティに設定します。 関連エンティティのリストなどの、ナビゲーション プロパティは設定されず、その値が null に設定される場合があります。 これにより、EF Core は必要以上のデータをフェッチしなくなります。これは、効率的な方法ですばやく要求を処理し、応答を返す必要がある、Web アプリケーションの場合に特に重要です。 _一括読み込み_を使用して、エンティティとのリレーションシップを含めるには、次のように、クエリで Include 拡張メソッドを使用してプロパティを指定します。 ```csharp // .Include requires using Microsoft.EntityFrameworkCore @@ -127,13 +125,15 @@ var brandsWithItems = await _context.CatalogBrands 複数のリレーションシップを含めることができます。また、ThenInclude を使用して、サブリレーションシップを含めることもできます。 EF Core は単一のクエリを実行して、エンティティの結果セットを取得します。 -関連データを読み込むために、*明示的読み込み*を使用することもできます。 明示的読み込みを使用すれば、既に取得されているエンティティに追加データを読み込むことができます。 これにはデータベースへの個別の要求が必要になるため、要求ごとに行われるデータベース ラウンド トリップの数を最小限に抑える必要がある、Web アプリケーションではお勧めできません。 +関連データを読み込むために、_明示的読み込み_を使用することもできます。 明示的読み込みを使用すれば、既に取得されているエンティティに追加データを読み込むことができます。 これにはデータベースへの個別の要求が必要になるため、要求ごとに行われるデータベース ラウンド トリップの数を最小限に抑える必要がある、Web アプリケーションではお勧めできません。 -*遅延読み込み*は、アプリケーションでの参照時に関連データを自動的に読み込む機能です。 現在、これは EF Core ではサポートされていませんが、明示的読み込みの場合と同様に、Web アプリケーションでは通常、無効にする必要があります。 +_遅延読み込み_は、アプリケーションでの参照時に関連データを自動的に読み込む機能です。 EF Core では、バージョン 2.1 で遅延読み込みのサポートが追加されました。 遅延読み込みは既定では有効になりません。`Microsoft.EntityFrameworkCore.Proxies` をインストールする必要があります。 明示的読み込みと同様、遅延読み込みは通常、Web アプリケーションでは無効にする必要があります。遅延読み込みを使用すると、各 Web 要求内で追加のデータベース クエリが行われるためです。 待機時間が短く、テストに使用されるデータ セットが小さい場合、残念ながら、遅延読み込みによって発生するオーバーヘッドについては開発時にあまり気付きません。 しかし、ユーザーやデータがより多く、待機時間がより長い運用環境では、追加のデータベース要求により、遅延読み込みを多用する Web アプリケーションのパフォーマンスが低下する可能性があります。 + +[Web アプリケーションでのエンティティの遅延読み込みを回避する](https://ardalis.com/avoid-lazy-loading-entities-in-asp-net-applications) ### 回復力のある接続 -SQL データベースなどの外部リソースが使用できなくなる場合があります。 一時的に使用できなくなった場合、アプリケーションは再試行ロジックを使用して、例外の発生を防ぐことができます。 この手法は一般的に*接続の復元性*と呼ばれます。 [指数バックオフを含む独自の再試行](https://docs.microsoft.com/azure/architecture/patterns/retry)手法は、最大再試行回数に達するまで、指数関数的に増加する待機時間で再試行することで実装できます。 この手法を使用すると、クラウド リソースが短時間、断続的に使用できなくなる可能性があり、その結果、一部の要求が失敗します。 +SQL データベースなどの外部リソースが使用できなくなる場合があります。 一時的に使用できなくなった場合、アプリケーションは再試行ロジックを使用して、例外の発生を防ぐことができます。 この手法は一般的に_接続の復元性_と呼ばれます。 [指数バックオフを含む独自の再試行](https://docs.microsoft.com/azure/architecture/patterns/retry)手法は、最大再試行回数に達するまで、指数関数的に増加する待機時間で再試行することで実装できます。 この手法を使用すると、クラウド リソースが短時間、断続的に使用できなくなる可能性があり、その結果、一部の要求が失敗します。 Azure SQL DB の場合、Entity Framework Core に内部データベース接続の復元機能と再試行ロジックが既に用意されています。 ただし、回復力のある EF Core 接続を使用する場合は、各 DbContext 接続に対して Entity Framework 実行戦略を有効にする必要があります。 @@ -153,19 +153,19 @@ public class Startup { sqlOptions.EnableRetryOnFailure( maxRetryCount: 5, - maxRetryDelay: TimeSpan.FromSeconds(30), - errorNumbersToAdd: null); + maxRetryDelay: TimeSpan.FromSeconds(30), + errorNumbersToAdd: null); }); }); } //... ``` - #### BeginTransaction と複数の DbContext を使用した実行戦略と明示的なトランザクション - - EF Core 接続で再試行を有効にすると、EF Core を使用して実行する各操作は、独自の再試行可能な操作になります。 一時的なエラーが発生した場合、SaveChanges への各クエリと各呼び出しは 1 つのユニットとして再試行されます。 - - 一方、BeginTransaction を使用してトランザクションを開始するコードの場合、1 ユニットとして扱う必要のある独自の操作グループを定義しています。エラーが発生した場合、トランザクション内のすべてがロールバックされます。 EF 実行戦略 (再試行ポリシー) を使用し、複数の DbContext からの SaveChanges をいくつかトランザクションに含める場合、そのトランザクションを実行しようとすると、次のような例外が表示されます。 +#### BeginTransaction と複数の DbContext を使用した実行戦略と明示的なトランザクション + +EF Core 接続で再試行を有効にすると、EF Core を使用して実行する各操作は、独自の再試行可能な操作になります。 一時的なエラーが発生した場合、SaveChanges への各クエリと各呼び出しは 1 つのユニットとして再試行されます。 + +一方、BeginTransaction を使用してトランザクションを開始するコードの場合、1 ユニットとして扱う必要のある独自の操作グループを定義しています。エラーが発生した場合、トランザクション内のすべてがロールバックされます。 EF 実行戦略 (再試行ポリシー) を使用し、複数の DbContext からの SaveChanges をいくつかトランザクションに含める場合、そのトランザクションを実行しようとすると、次のような例外が表示されます。 System.InvalidOperationException: 構成された実行戦略 'SqlServerRetryingExecutionStrategy' は、ユーザーが開始したトランザクションをサポートしていません。 'DbContext.Database.CreateExecutionStrategy()' から返された実行戦略を使用して、再試行可能なユニットとしてトランザクション内のすべての操作を実行します。 @@ -176,7 +176,7 @@ System.InvalidOperationException: 構成された実行戦略 'SqlServerRetrying // within an explicit transaction // See: // https://docs.microsoft.com/ef/core/miscellaneous/connection-resiliency -var strategy = _catalogContext.Database.CreateExecutionStrategy(); +var strategy = _catalogContext.Database.CreateExecutionStrategy(); await strategy.ExecuteAsync(async () => { // Achieving atomicity between original Catalog database operation and the @@ -185,7 +185,7 @@ await strategy.ExecuteAsync(async () => { _catalogContext.CatalogItems.Update(catalogItem); await _catalogContext.SaveChangesAsync(); - + // Save to EventLog only if product price changed if (raiseProductPriceChangedEvent) await _integrationEventLogService.SaveEventAsync(priceChangedEvent); @@ -197,12 +197,13 @@ await strategy.ExecuteAsync(async () => 最初の DbContext は \_catalogContext で、2 つ目の DbContext は \_integrationEventLogService オブジェクト内にあります。 最後に、Commit アクションが、複数の DbContext で EF 実行戦略を使用して実行されます。 > ### 参照 – Entity Framework Core +> > - **EF Core ドキュメント** -> +> > - **EF Core: 関連データ** -> +> > - **ASPNET アプリケーションでのエンティティの遅延読み込みを回避する** -> +> ## EF Core または micro-ORM の選択 @@ -271,8 +272,7 @@ NoSQL データベースには、リレーショナル データベースでは ## Azure DocumentDB -Azure DocumentDB はフル マネージドの NoSQL データベース サービスであり、クラウドベースのスキーマレスなデータ ストレージを提供します。 DocumentDB は、高速で予測可能なパフォーマンス、高可用性、エラスティック スケーリング、およびグローバル配布用に作成されています。 NoSQL データベースであるにもかかわらず、開発者は JSON データで豊富で使い慣れた SQL クエリ機能を使用できます。 DocumentDB のすべてのリソースは、JSON ドキュメントとして格納されます。 リソースは、*アイテム* (メタデータを含むドキュメント) および*フィード* (アイテムのコレクション) として管理されます。 図 8-2 は、さまざまな DocumentDB リソース間の関係を示しています。 - +Azure DocumentDB はフル マネージドの NoSQL データベース サービスであり、クラウドベースのスキーマレスなデータ ストレージを提供します。 DocumentDB は、高速で予測可能なパフォーマンス、高可用性、エラスティック スケーリング、およびグローバル配布用に作成されています。 NoSQL データベースであるにもかかわらず、開発者は JSON データで豊富で使い慣れた SQL クエリ機能を使用できます。 DocumentDB のすべてのリソースは、JSON ドキュメントとして格納されます。 リソースは、_アイテム_ (メタデータを含むドキュメント) および_フィード_ (アイテムのコレクション) として管理されます。 図 8-2 は、さまざまな DocumentDB リソース間の関係を示しています。 ![DocumentDB (NoSQL JSON データベース) のリソース間の階層関係](./media/image8-2.png) @@ -282,25 +282,25 @@ DocumentDB クエリ言語は、JSON ドキュメントを照会するための **参照 – DocumentDB** -- DocumentDB の概要\ - +- DocumentDB の概要\ + ## その他の永続性オプション リレーショナルおよび NoSQL ストレージ オプションに加え、ASP.NET Core アプリケーションでは Azure Storage を使用して、クラウドベースのスケーラブルな方法でさまざまなデータ形式とファイルを格納できます。 Azure Storage は非常にスケーラブルであるため、最初に少量のデータを格納し、アプリケーションで必要になった場合に数百または数テラバイトのデータを格納するようにスケール アップできます。 Azure Storage では次の 4 つの種類のデータがサポートされます。 -- 非構造化テキストまたはバイナリ ストレージ用の Blob Storage。これは、オブジェクト ストレージとも呼ばれます。 +- 非構造化テキストまたはバイナリ ストレージ用の Blob Storage。これは、オブジェクト ストレージとも呼ばれます。 -- 行キーを使用してアクセス可能な、構造化データセット用の Table Storage。 +- 行キーを使用してアクセス可能な、構造化データセット用の Table Storage。 -- 信頼性の高いキューベースのメッセージング用の Queue Storage。 +- 信頼性の高いキューベースのメッセージング用の Queue Storage。 -- Azure 仮想マシンとオンプレミス アプリケーション間での共有ファイル アクセス用の File Storage。 +- Azure 仮想マシンとオンプレミス アプリケーション間での共有ファイル アクセス用の File Storage。 **参照 – Azure Storage** -- Azure Storage の概要\ - +- Azure Storage の概要\ + ## キャッシュ @@ -316,16 +316,17 @@ ASP.NET Core では、2 つのレベルの応答キャッシュがサポート [ResponseCache(Duration = 60)] public IActionResult Contact() { } - + ViewData["Message"] = "Your contact page."; return View(); } +``` -The above example will result in the following header being added to the response, instructing clients to cache the result for up to 60 seconds. +前の例では、応答に次のヘッダーが追加され、最大で 60 秒間、結果をキャッシュするようクライアントに指示します。 Cache-Control: public,max-age=60 -In order to add server-side in-memory caching to the application, you must reference the Microsoft.AspNetCore.ResponseCaching NuGet package, and then add the Response Caching middleware. This middleware is configured in both ConfigureServices and Configure in Startup: +サーバー側のメモリ内キャッシュをアプリケーションに追加するには、Microsoft.AspNetCore.ResponseCaching NuGet パッケージを参照し、応答キャッシュ ミドルウェアを追加する必要があります。 このミドルウェは、Startup の ConfigureServices と Configure の両方で構成されます。 ```csharp public void ConfigureServices(IServiceCollection services) @@ -339,11 +340,11 @@ public void Configure(IApplicationBuilder app) } ``` -応答キャッシュ ミドルウェアは、カスタマイズ可能な一連の条件に基づいて、自動的に応答をキャッシュします。 既定では、GET または HEAD メソッドを使用して要求された 200 (OK) の応答のみがキャッシュされます。 さらに、要求には、Cache-Control: public ヘッダーを含む応答が必要であり、Authorization や Set-Cookie のヘッダーを含めることはできません。 [応答キャッシュ ミドルウェアで使用されるキャッシュ条件の完全なリスト](https://docs.microsoft.com/aspnet/core/performance/caching/middleware#conditions-for-caching)を参照してください。 +応答キャッシュ ミドルウェアは、カスタマイズ可能な一連の条件に基づいて、自動的に応答をキャッシュします。 既定では、GET または HEAD メソッドを使用して要求された 200 (OK) の応答のみがキャッシュされます。 さらに、要求には、Cache-Control: public ヘッダーを含む応答が必要であり、Authorization や Set-Cookie のヘッダーを含めることはできません。 [応答キャッシュ ミドルウェアで使用されるキャッシュ条件の完全なリスト](/aspnet/core/performance/caching/middleware#conditions-for-caching)を参照してください。 ### データ キャッシュ -完全な Web 応答のキャッシュではなく (または、このようなキャッシュに加えて)、個々のデータ クエリの結果をキャッシュすることができます。 その場合、Web サーバーでメモリ内キャッシュを使用するか、[分散キャッシュ](https://docs.microsoft.com/aspnet/core/performance/caching/distributed)を使用できます。 このセクションでは、メモリ内キャッシュの実装方法を示します。 +完全な Web 応答のキャッシュではなく (または、このようなキャッシュに加えて)、個々のデータ クエリの結果をキャッシュすることができます。 その場合、Web サーバーでメモリ内キャッシュを使用するか、[分散キャッシュ](/aspnet/core/performance/caching/distributed)を使用できます。 このセクションでは、メモリ内キャッシュの実装方法を示します。 次のように、ConfigureServices でメモリ (または分散) キャッシュのサポートを追加します。 @@ -374,7 +375,7 @@ public class CachedCatalogService : ICatalogService _cache = cache; _catalogService = catalogService; } - + public async Task> GetBrands() { return await _cache.GetOrCreateAsync(_brandsKey, async entry => @@ -383,7 +384,7 @@ public class CachedCatalogService : ICatalogService return await _catalogService.GetBrands(); }); } - + public async Task GetCatalogItems(int pageIndex, int itemsPage, int? brandID, int? typeId) { string cacheKey = String.Format(_itemsKeyTemplate, pageIndex, itemsPage, brandID, typeId); @@ -393,7 +394,7 @@ public class CachedCatalogService : ICatalogService return await _catalogService.GetCatalogItems(pageIndex, itemsPage, brandID, typeId); }); } - + public async Task> GetTypes() { return await _cache.GetOrCreateAsync(_typesKey, async entry => @@ -415,7 +416,7 @@ services.AddScoped(); こうすることで、カタログ データをフェッチするデータセット呼び出しは、要求ごとではなく、1 分ごとに 1 回だけ行われるようになります。 サイトへのトラフィックによっては、データベースに対して行われるクエリの数と、このサービスによって公開される 3 つのすべてのクエリに現在依存しているホーム ページの平均ページ読み込み時間に非常に大きく影響する場合があります。 -キャッシュの実装時に問題になるのは、*古いデータ*です。つまり、データがソースで変更されても、その古いバージョンのデータがキャッシュに保持されます。 この問題を緩和する簡単な方法は、短いキャッシュ期間を使用することです。ビジー状態のアプリケーションの場合、データのキャッシュ期間を延長することで得られる限られた追加の利点があるためです。 たとえば、単一のデータベース クエリを実行し、1 秒ごとに 10 回要求されるページがあるとします。 このページが 1 分間キャッシュされると、1 分ごとに実行されるデータベース クエリの数は 600 から 1 に減り、99.8% の減少率となります。 代わりにキャッシュ期間を 1 時間にした場合、全体的な減少率は 99.997% となりますが、古いデータの確率的および潜在的な経過期間はどちらも大幅に増えます。 +キャッシュの実装時に問題になるのは、_古いデータ_です。つまり、データがソースで変更されても、その古いバージョンのデータがキャッシュに保持されます。 この問題を緩和する簡単な方法は、短いキャッシュ期間を使用することです。ビジー状態のアプリケーションの場合、データのキャッシュ期間を延長することで得られる限られた追加の利点があるためです。 たとえば、単一のデータベース クエリを実行し、1 秒ごとに 10 回要求されるページがあるとします。 このページが 1 分間キャッシュされると、1 分ごとに実行されるデータベース クエリの数は 600 から 1 に減り、99.8% の減少率となります。 代わりにキャッシュ期間を 1 時間にした場合、全体的な減少率は 99.997% となりますが、古いデータの確率的および潜在的な経過期間はどちらも大幅に増えます。 含まれているデータを更新する場合、事前にキャッシュ エントリを削除することもできます。 キーがわかっている場合は、個々のエントリを削除できます。 @@ -437,6 +438,8 @@ new CancellationChangeToken(cts.Token)); _cache.Get("cts").Cancel(); ``` +キャッシュでは、データベースから同じ値を繰り返し要求する Web ページのパフォーマンスを大幅に向上させることができます。 キャッシュを適用する前に、必ずデータ アクセスとページのパフォーマンスを測定し、改善の必要性があると判断した場合にのみ、キャッシュを適用するようにしてください。 キャッシュでは Web サーバーのメモリ リソースが消費され、アプリケーションの複雑さが増すため、この手法を使用して不完全な最適化を行わないことが重要です。 + >[!div class="step-by-step"] [前へ](develop-asp-net-core-mvc-apps.md) [次へ](test-asp-net-core-mvc-apps.md) diff --git a/docs/standard/threading/autoresetevent.md b/docs/standard/threading/autoresetevent.md index a7b91648a79..1cecb452415 100644 --- a/docs/standard/threading/autoresetevent.md +++ b/docs/standard/threading/autoresetevent.md @@ -1,25 +1,26 @@ --- -title: AutoResetEvent -ms.date: 03/30/2017 -ms.technology: dotnet-standard -helpviewer_keywords: -- threading [.NET Framework], AutoResetEvent class -- AutoResetEvent class -ms.assetid: 6d39c48d-6b37-4a9b-8631-f2924cfd9c18 -author: rpetrusha -ms.author: ronpet -ms.openlocfilehash: a4ab06993eed4b39746875a6ef3ebfad5edbd2e6 -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 +title: AutoResetEvent +ms.date: 03/30/2017 +ms.technology: dotnet-standard +helpviewer_keywords: +- threading [.NET Framework], AutoResetEvent class +- AutoResetEvent class +ms.assetid: 6d39c48d-6b37-4a9b-8631-f2924cfd9c18 +author: rpetrusha +ms.author: ronpet +ms.openlocfilehash: c1785ce223f0dcd4da7ea6ef9fa3a3e897a39dca +ms.sourcegitcommit: dc02d7d95f1e3efcc7166eaf431b0ec0dc9d8dca +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/02/2018 +ms.locfileid: "37143519" --- # AutoResetEvent クラスは、単一の待機スレッドを解放した後、シグナル状態になると自動的にリセットするローカル待機ハンドル イベントを表します。 このクラスは、その基底クラス の特殊なケースを表します。 自動リセット イベントの使用方法と機能については、[EventWaitHandle](../../../docs/standard/threading/eventwaithandle.md) の概念に関する文書を参照してください。 オブジェクトは、単一の待機スレッドが解放された後、システムによって自動的に非シグナルにリセットされます。 待機しているスレッドがない場合でも、イベント オブジェクトの状態はシグナルのままです。 は、`bManualReset` 引数に対して `false` を指定する、Win32 `CreateEvent` 呼び出しに対応します。 - の使用例については、「[Monitor クラス](http://msdn.microsoft.com/library/33fe4aef-b44b-42fd-9e72-c908e39e75db)」を参照してください。 + の使用例については、「」を参照してください。 ## 参照 diff --git a/docs/standard/threading/threading-objects-and-features.md b/docs/standard/threading/threading-objects-and-features.md index 4fd8fe5348c..abfbcf6ce65 100644 --- a/docs/standard/threading/threading-objects-and-features.md +++ b/docs/standard/threading/threading-objects-and-features.md @@ -1,31 +1,32 @@ --- -title: スレッド処理オブジェクトと機能 -ms.date: 03/30/2017 -ms.technology: dotnet-standard -helpviewer_keywords: -- threading [.NET Framework], features -- managed threading -ms.assetid: 239b2e8d-581b-4ca3-992b-0e8525b9321c -author: rpetrusha -ms.author: ronpet -ms.openlocfilehash: 02f88faab6ddbaa026e73ad61bc63fbe8e5e00ed -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33591328" +title: スレッド処理オブジェクトと機能 +ms.date: 03/30/2017 +ms.technology: dotnet-standard +helpviewer_keywords: +- threading [.NET Framework], features +- managed threading +ms.assetid: 239b2e8d-581b-4ca3-992b-0e8525b9321c +author: rpetrusha +ms.author: ronpet +ms.openlocfilehash: 1d689aeb91ad79b776c3b93c1809ec46947ea60b +ms.sourcegitcommit: 59b51cd7c95c75be85bd6ef715e9ef8c85720bac +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/06/2018 +ms.locfileid: "37874788" --- # スレッド処理オブジェクトと機能 -.NET Framework には、マルチスレッド アプリケーションの作成と管理に役立つ多くのオブジェクトが用意されています。 マネージ スレッドは、 クラスによって表されます。 クラスを使用すると、マルチスレッドのバックグラウンド タスクを簡単に作成し、管理できます。 クラスは、ユーザー インターフェイスと対話するタスクについてそれと同じことを実現します。 クラスは、指定された間隔でバックグラウンド タスクを実行します。 +.NET Framework には、マルチスレッド アプリケーションの作成と管理に役立つ多くのオブジェクトが用意されています。 マネージド スレッドは、 クラスによって表されます。 クラスを使用すると、マルチスレッドのバックグラウンド タスクを簡単に作成し、管理できます。 クラスは、ユーザー インターフェイスと対話するタスクについてそれと同じことを実現します。 クラスは、指定された間隔でバックグラウンド タスクを実行します。 さらに、.NET Framework Version 2.0 で導入された クラスや クラスなど、スレッドの活動を同期するクラスも数多くあります。 これらのクラスの機能の比較については、「[同期プリミティブの概要](../../../docs/standard/threading/overview-of-synchronization-primitives.md)」を参照してください。 ## このセクションの内容 - [マネージ スレッド プール](../../../docs/standard/threading/the-managed-thread-pool.md) + + [マネージド スレッド プール](../../../docs/standard/threading/the-managed-thread-pool.md) **ThreadPool** クラスについて説明します。このクラスを利用すると、開発者はスレッド管理を意識する必要なく、スレッドにタスクの実行を要求できます。 [タイマー](../../../docs/standard/threading/timers.md) - **Timer** を使用して、指定された時間に呼び出されるデリゲートを指定する方法を説明します。 + マルチスレッド環境で使用できるタイマーについて説明します。 [モニター](http://msdn.microsoft.com/library/33fe4aef-b44b-42fd-9e72-c908e39e75db) **Monitor** クラスを使用してメンバーへのアクセスを同期したり、独自の種類のスレッド管理を構築したりする方法を説明します。 @@ -34,7 +35,7 @@ ms.locfileid: "33591328" クラスについて説明します。このクラスは、イベント待機ハンドル、ミューテックス、およびセマフォ用の抽象基底クラスで、複数の同期イベントを待機できるようにします。 [EventWaitHandle、AutoResetEvent、CountdownEvent、ManualResetEvent](../../../docs/standard/threading/eventwaithandle-autoresetevent-countdownevent-manualresetevent.md) - 通知を行ったり通知を待機したりすることによりスレッドの活動を同期するために使用するマネージ イベント待機ハンドルについて説明します。 + 通知を行ったり通知を待機したりすることによりスレッドの活動を同期するために使用するマネージド イベント待機ハンドルについて説明します。 [ミューテックス](../../../docs/standard/threading/mutexes.md) オブジェクトへのアクセスの同期、または独自の同期機構の構築を を使用して行う方法を説明します。 @@ -49,7 +50,7 @@ ms.locfileid: "33591328" オブジェクトについて説明し、このオブジェクトを使用して、制限されたリソースへのアクセスを制御する方法を示します。 [同期プリミティブの概要](../../../docs/standard/threading/overview-of-synchronization-primitives.md) - マネージ スレッドをロックおよび同期するために用意されている .NET Framework のクラスの機能を比較します。 + マネージド スレッドをロックおよび同期するために用意されている .NET Framework のクラスの機能を比較します。 [バリア](../../../docs/standard/threading/barrier.md) 段階的な操作におけるスレッドの調整のためのバリア パターンを実装する オブジェクトについて説明します。 @@ -62,7 +63,8 @@ ms.locfileid: "33591328" ## 参照 - **Thread** クラスのリファレンス ドキュメントです。このクラスは、アンマネージ コードから作成されたか、マネージ アプリケーションで作成されたかにかかわらず、マネージ スレッドを表します。 + + **Thread** クラスのリファレンス ドキュメントです。このクラスは、アンマネージド コードから作成されたか、マネージド アプリケーションで作成されたかにかかわらず、マネージド スレッドを表します。 ユーザー インターフェイスと対話し、ユーザー インターフェイス スレッドで生成されるイベントを介して通信するバックグラウンド タスクを有効にします。 diff --git a/docs/standard/threading/timers.md b/docs/standard/threading/timers.md index f467ee5a2de..76724aa5dad 100644 --- a/docs/standard/threading/timers.md +++ b/docs/standard/threading/timers.md @@ -1,38 +1,63 @@ --- -title: タイマー -ms.date: 03/30/2017 -ms.technology: dotnet-standard -dev_langs: -- csharp -- vb -- cpp -helpviewer_keywords: -- threading [.NET Framework], timers -- timers, about timers -ms.assetid: 7091500d-be18-499b-a942-95366ce185e5 -author: rpetrusha -ms.author: ronpet -ms.openlocfilehash: 478484651bf839f842148f0b4164c9387db3b98a -ms.sourcegitcommit: 3d5d33f384eeba41b2dff79d096f47ccc8d8f03d -ms.translationtype: HT -ms.contentlocale: ja-JP -ms.lasthandoff: 05/04/2018 -ms.locfileid: "33584958" +title: タイマー +description: マルチスレッド環境で使用する .NET タイマーについて説明します。 +ms.date: 07/03/2018 +ms.technology: dotnet-standard +dev_langs: +- csharp +- vb +- cpp +helpviewer_keywords: +- threading [.NET Framework], timers +- timers, about timers +ms.assetid: 7091500d-be18-499b-a942-95366ce185e5 +author: pkulikov +ms.author: ronpet +ms.openlocfilehash: ae41c535d8bc1c0a05174b9051ba34f1a0a34638 +ms.sourcegitcommit: 59b51cd7c95c75be85bd6ef715e9ef8c85720bac +ms.translationtype: HT +ms.contentlocale: ja-JP +ms.lasthandoff: 07/06/2018 +ms.locfileid: "37875067" --- # タイマー -タイマーとは、指定時刻に指定のデリゲートを呼び出す軽量オブジェクトのことです。 スレッド プール内の 1 つのスレッドが、待機操作を実行します。 - - クラスの使用法は単純です。 **Timer** を作成するには、コールバック メソッドへの デリゲート、コールバックに渡される状態を表すオブジェクト、最初に発生する時間、コールバック呼び出しの間隔を表す時間を渡します。 保留中のタイマーを取り消すには、**Timer.Dispose** 関数を呼び出します。 - + +.NET には、マルチスレッド環境で使用するタイマーが 2 つあります。 + +- スレッドで決まった間隔を空けながら呼び出しメソッドを 1 つ実行します。 +- は既定では、 スレッドで決まった間隔を空けながらイベントを発生させます。 + > [!NOTE] -> 他にも 2 つのタイマー クラスがあります。 クラスは、ビジュアルなデザイナーを操作するコントロールで、ユーザー インターフェイスのコンテキストで使用するように設計されています。このクラスは、ユーザー インターフェイス スレッドでイベントを発生させます。 クラスは から派生するため、ビジュアルなデザイナーで使用できます。このクラスもイベントを発生させますが、イベントは スレッドで発生します。 クラスは スレッドでコールバックを行い、イベント モデルは使用しません。 またこのクラスは、状態オブジェクトをコールバック メソッドに提供します。他のタイマーは状態オブジェクトを提供しません。 このクラスは、非常に軽量です。 - - 次のコード例は、1 秒 (1000 ミリ秒) 後に起動し、**Enter** キーを押すまで 1 秒ごとに時を刻むタイマーを開始します。 実行中にタイマーがガベージ コレクションの対象とならないように、このタイマーへの参照を含む変数はクラス レベルのフィールドとします。 積極的なガベージ コレクションの詳細については、「」を参照してください。 - - [!code-cpp[System.Threading.Timer#2](../../../samples/snippets/cpp/VS_Snippets_CLR_System/system.Threading.Timer/CPP/source2.cpp#2)] - [!code-csharp[System.Threading.Timer#2](../../../samples/snippets/csharp/VS_Snippets_CLR_System/system.Threading.Timer/CS/source2.cs#2)] - [!code-vb[System.Threading.Timer#2](../../../samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Threading.Timer/VB/source2.vb#2)] +> 一部の .NET 実装には追加タイマーが含まれています。 +> +> - : 一定の間隔でイベントを発生させる Windows フォーム コンポーネント。 このコンポーネントにはユーザー インターフェイスがなく、シングルスレッド環境で使用するように設計されています。 +> - : 非同期または同期の Web ページのポストバックを一定の間隔で実行する ASP.NET コンポーネント。 +> - : 指定の間隔と指定の優先順位で処理される キューに統合されるタイマー。 + +## System.Threading.Timer クラス + + クラスによって、指定の間隔でデリゲートを連続的に呼び出すことができます。 このクラスを使用し、指定の間隔でデリゲートの呼び出しを 1 つスケジュールすることもできます。 デリゲートは スレッドで実行されます。 + + オブジェクトを作成するとき、呼び出しメソッドを定義する デリゲート、呼び出しに渡される任意の状態オブジェクト、最初の呼び出しまで遅らせる時間、呼び出し間隔を指定します。 保留中のタイマーを取り消すには、 メソッドを呼び出します。 + +次の例では、1 秒 (1000 ミリ秒) 後に最初の指定デリゲートを呼び出し、その後、2 秒おきに呼び出すタイマーが作成されます。 この例の状態オブジェクトは、デリゲートを呼び出す回数を数えるために使用されます。 デリゲートが少なくとも 10 回呼び出されると、タイマーが停止します。 + +[!code-cpp[System.Threading.Timer#2](../../../samples/snippets/cpp/VS_Snippets_CLR_System/system.Threading.Timer/CPP/source2.cpp#2)] +[!code-csharp[System.Threading.Timer#2](../../../samples/snippets/csharp/VS_Snippets_CLR_System/system.Threading.Timer/CS/source2.cs#2)] +[!code-vb[System.Threading.Timer#2](../../../samples/snippets/visualbasic/VS_Snippets_CLR_System/system.Threading.Timer/VB/source2.vb#2)] + +使用例を含む詳細については、「」を参照してください。 + +## System.Timers.Timer クラス + +マルチスレッド環境で使用できる別のタイマーが です。このタイマーは既定で、 スレッドでイベントを発生させます。 + + オブジェクトを作成するとき、 イベントを発生させる間隔を指定できます。 プロパティを使用し、タイマーが イベントを発生させるかどうかを示します。 指定間隔の経過後、1 回だけ イベントを発生させる必要がある場合、 を `false` に設定します。 プロパティの既定値は `true` です。 プロパティで定義される間隔で イベントが発生します。 + +使用例を含む詳細については、「」を参照してください。 -## 参照 - - [スレッド処理オブジェクトと機能](../../../docs/standard/threading/threading-objects-and-features.md) +## 関連項目 + + + + [スレッド処理オブジェクトと機能](threading-objects-and-features.md) diff --git a/includes/topic-appliesto-net-core-21plus.md b/includes/topic-appliesto-net-core-21plus.md new file mode 100644 index 00000000000..7734d5662d8 --- /dev/null +++ b/includes/topic-appliesto-net-core-21plus.md @@ -0,0 +1 @@ +**このトピックの対象: ✓** .NET Core SDK 2.1.300 以降のバージョン diff --git a/includes/topic-appliesto-net-core-2plus.md b/includes/topic-appliesto-net-core-2plus.md index ff783611b78..ea64d8a80de 100644 --- a/includes/topic-appliesto-net-core-2plus.md +++ b/includes/topic-appliesto-net-core-2plus.md @@ -1 +1 @@ -**このトピックの対象: ✓**.NET Core SDK 2.0 +**このトピックの対象: ✓** .NET Core SDK 2.0 以降のバージョン