へっぽこプログラマーの備忘録
プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。
menu
keyboard_arrow_up
Top
search
close
home
ホーム
computer
PC一般
construction
開発環境・ツール
code
プログラミング
home
ホーム
computer
PC一般
construction
開発環境・ツール
code
プログラミング
Home
›
Entity Framework Core
›
Entity Framework Core におけるデータの取得
2018/01/17
Entity Framework Core におけるデータの取得
update
event_note
label
Entity Framework Core
Entity Framework Core を使ってデータベースからデータを取得する方法についてです。
## 環境 - Visual Studio 2017 - .NET Core 2.0 - Entity Framework Core 2.0 ## 基本 ### 全データの取得 ```cs using (var context = new BloggingContext()) { var blogs = context.Blogs.ToList(); } ``` ### 単一のエンティティ(レコード)を取得 ```cs using (var context = new BloggingContext()) { var blog = context.Blogs .Single(b => b.BlogId == 1); } ``` ### フィルタリング ```cs using (var context = new BloggingContext()) { var blogs = context.Blogs .Where(b => b.Url.Contains("dotnet")) .ToList(); } ``` ## 関連するデータの取得 Entity Framework Core におけるリレーションシップについては以下を参照してください。 - http://kuttsun.blogspot.jp/2018/01/entity-framework-core_11.html ここでは上記のときと同じ以下のモデルを例とします。 ```cs // Blog is the principal entity public class Blog { // Blog.BlogId is the principal key // (in this case it is a primary key rather than an alternate key) public int BlogId { get; set; } public string Url { get; set; } // Blog.Posts is a collection navigation property public List
Posts { get; set; } } // Post is the dependent entity public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } // Post.BlogId is the foreign key public int BlogId { get; set; } // Post.Blog is a reference navigation property // Post.Blog is the inverse navigation property of Blog.Posts (and vice versa) public Blog Blog { get; set; } } ``` [公式サイト](https://docs.microsoft.com/en-us/ef/core/querying/related-data)によると、関連データを取得する際のO/Rマッピングのパターンは以下の3パターンがあるようです。 - **Eager loading** 関連するデータが初期クエリの一部としてデータベースからロードされる - **Explicit loading** 関連するデータが後でデータベースから明示的にロードされる - **Lazy loading** Navigation property にアクセスしたときに関連するデータがデータベースから透過的にロードされる 直訳しただけですが、分かったような分からないような・・・。 以下、ほぼ訳しただけの内容です。 ### Eager loading `Include` メソッドを使用して、クエリの結果に含める関連データを指定できます。 以下の例では、`blogs` には、関連する `Posts` プロパティのインスタンスを持った状態でデータが取得されます。 ```cs using (var context = new BloggingContext()) { var blogs = context.Blogs .Include(blog => blog.Posts) .ToList(); } ``` もし `Include` がなかったら、`blogs` の `Posts` プロパティは null になります。 複数の関連データを取得したい場合でも、以下のように1つのクエリで指定できます。 ```cs using (var context = new BloggingContext()) { var blogs = context.Blogs .Include(blog => blog.Posts) .Include(blog => blog.Owner) .ToList(); } ``` #### 複数のレベルのデータを取得 エンティティが複数の関係を持つ場合、`ThenInclude` メソッドを使用して複数のレベルの関連データを含めることができます。 次の例では、すべての `blog` 関連する `post`、および各 `post` の `Author` を読み込みます。 ```cs using (var context = new BloggingContext()) { var blogs = context.Blogs .Include(blog => blog.Posts) .ThenInclude(post => post.Author) .ToList(); } ``` さらに `ThenInclude` を呼び出すことで、連鎖的に関連データを取得できます。 ```cs using (var context = new BloggingContext()) { var blogs = context.Blogs .Include(blog => blog.Posts) .ThenInclude(post => post.Author) .ThenInclude(author => author.Photo) .ToList(); } ``` これらを組み合わせて、1つのクエリでの複数のレベルおよび複数のルートから関連データを取得できます。 ```cs using (var context = new BloggingContext()) { var blogs = context.Blogs .Include(blog => blog.Posts) .ThenInclude(post => post.Author) .ThenInclude(author => author.Photo) .Include(blog => blog.Owner) .ThenInclude(owner => owner.Photo) .ToList(); } ``` 含まれているエンティティの1つに複数の関連エンティティを含めることができます。 例えば、`blogs` に対するクエリのおいて、`Posts` を取得し、さらに `Posts` の中の `Author` と `Tags` を取得したい場合などです。 これを行うには、それぞれに対してルートからインクルードパスを指定する必要があります。 例えば、以下のように、`Blog -> Posts -> Author` `Blog -> Posts -> Tags` のようにします。 ```cs using (var context = new BloggingContext()) { var blogs = context.Blogs .Include(blog => blog.Posts) .ThenInclude(post => post.Author) .Include(blog => blog.Posts) .ThenInclude(post => post.Tags) .ToList(); } ``` #### 無視される内容 クエリが開始されたときのエンティティのインスタンスを返さないようにクエリを変更すると、`Include` 演算子は無視されます。 次の例では、`Include` 演算子は `Blog` に基づいていますが、`Select` 演算子はクエリを変更して匿名型を返すために使用されています。 この場合、`Include` 演算子は何の効果もありません。 ```cs using (var context = new BloggingContext()) { var blogs = context.Blogs .Include(blog => blog.Posts) .Select(blog => new { Id = blog.BlogId, Url = blog.Url }) .ToList(); } ``` デフォルトでは、`Include` 演算子が無視されると、EF Core は警告をだします。 ロギング出力の表示の詳細については、[Logging](https://docs.microsoft.com/en-us/ef/core/miscellaneous/logging) を参照してください。 `Include` 演算子が無視されたときに、例外を投げるか何もしないか、振る舞いを変更することができます。 これは、コンテキストのオプションを設定するときに行われます。 (通常は `DbContext.OnConfiguring` または ASP.NET Core を使用している場合は `Startup.cs` で行います。) ```cs protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFQuerying;Trusted_Connection=True;ConnectRetryCount=0") .ConfigureWarnings(warnings => warnings.Throw(CoreEventId.IncludeIgnoredWarning)); } ``` ### Explicit loading Navigation property は、`DbContext.Entry(...)` API を使用して明示的に読み込むことができます。 ```cs using (var context = new BloggingContext()) { var blog = context.Blogs .Single(b => b.BlogId == 1); context.Entry(blog) .Collection(b => b.Posts) .Load(); context.Entry(blog) .Reference(b => b.Owner) .Load(); } ``` 関連するエンティティを返すクエリを個別に実行することによって、Navigation property を明示的にロードすることもできます。 #### Querying related entities また、Navigation property の内容を表す LINQ クエリを取得することもできます。 これにより、関連エンティティをメモリにロードせずに `Count` 演算子を実行したりすることができます。 ```cs using (var context = new BloggingContext()) { var blog = context.Blogs .Single(b => b.BlogId == 1); var postCount = context.Entry(blog) .Collection(b => b.Posts) .Query() .Count(); } ``` また、関連エンティティをフィルタリングしてメモリにロードすることもできます。 ```cs using (var context = new BloggingContext()) { var blog = context.Blogs .Single(b => b.BlogId == 1); var goodPosts = context.Entry(blog) .Collection(b => b.Posts) .Query() .Where(p => p.Rating > 3) .ToList(); } ``` ### Lazy loading EF Core ではまだサポートされていません。 ### データのリレーションシップとシリアライズ EF Core は自動的に Navigation property を修正するので、オブジェクトグラフに循環構造を持つことになります。 例えば、`blog` とそれに関連する `Posts` を読み込むと、`Posts` コレクションに対する参照を持った `blog` オブジェクトという結果になります。 `Posts` コレクション内のそれぞれ要素は、`blog` への参照を持つことになります。 一部のシリアライゼーションフレームワークでは、このような循環は許可されません。 たとえば、Json.NET では循環構造が発見された場合、次の例外をスローします。 > Newtonsoft.Json.JsonSerializationException: Self referencing loop detected for property 'Blog' with type 'MyApplication.Models.Blog'. ASP.NET Core を使用している場合は、オブジェクトグラフで見つかった循環を無視するようにJson.NETを設定できます。 これは `Startup.cs` の `ConfigureServices(...)` メソッドで行われます。
tweet
facebook
Pocket
B!
はてブ
LINE
chevron_left
chevron_right
Translate
Popular Posts
TortoiseGit でコミットメッセージを変更する
image
NO IMAGE
smbclient で session setup failed: NT_STATUS_LOGON_FAILURE が表示される
Docker for Windows の設定
[Python] 文字列の判定で、None と空文字を同時に判定する
TortoiseGit でブランチ間の差分を見る
image
NO IMAGE
マージ元ブランチとマージ先ブランチ
[Python] matplotlib で plot する際に "Tcl_AsyncDelete: async handler deleted by the wrong thread" というエラーがでる
[Python] Tesseract で OCR を行ったら `UnicodeEncodeError: 'ascii' codec can't encode characters` のエラーが表示された
image
NO IMAGE
GitLab Runner でクローンする URL を変更する
image
NO IMAGE
Visual Studio で文字がにじむ(ぼやける)
Labels
.NET Core
31
.NET Framework
17
.NET Standard
2
AdminLTE
1
AI
1
Apache
3
AppVeyor
2
AsciiDoc
3
ASP.NET Core
55
Atom
4
AWS
5
AWS Cloud9
4
blockdiag
1
Blogger
13
Bootstrap
3
C/C++
6
C#
106
CentOS
3
Chrome
1
Chronograf
3
chrony
1
Codecov
1
CSS
1
Docker
79
DokuWiki
4
Doxygen
1
draw.io
1
EasyTag
1
Electron
1
Electron.NET
2
Entity Framework Core
9
Excel
2
FFmpeg
3
Firefox
6
Flask
1
Git
19
GitBook
4
GitBucket
7
GitHub
7
GitLab
39
Go
1
Google
1
Google Cloud Platform
1
Grafana
13
GStreamer
2
HTML
5
IIS
8
InfluxDB
14
JavaScript
15
Jenkins
7
Linux
34
Log4View
1
MahApps.Metro
3
MaterialDesignInXamlToolkit
1
MkDocs
2
MongoDB
5
MVC
1
MVVM
6
nginx
3
NLog
3
Node.js
8
npm
1
NVIDIA
3
onvif
1
OpenAPI
2
OpenCV
4
OpenSSL
3
OpenVINO
2
ownCloud
2
pandas
1
Pine Script
1
PlantUML
5
Portainer
3
PowerShell
8
Prism
2
PySide
17
Python
85
PyTorch
1
RabbitVCS
1
Razor
3
Redmine
33
Redoc
1
remark.js
2
rocketchat
10
Ruby
3
scikit-learn
1
SignalR
1
Slack
1
Socket.IO
1
SonarQube
5
Sphinx
10
SQL Server
5
SQLite
1
StableDiffusion
1
Subversion
2
Swagger
1
Swarmpit
1
Syslog
3
Telegraf
6
Tesseract
3
TestLink
2
Tomcat
2
TortoiseGit
11
TortoiseSVN
2
Trading View
1
Traefik
3
Travis CI
1
Ubuntu
31
Visual Studio
39
Visual Studio Code
10
VSCode
8
Vue.js
8
Windows
62
Windows 10
5
Windows ADK
1
Windows API
2
Windows Embedded
4
wkhtmltopdf
2
Word
3
WPF
12
WSL
5
WSL2
5
Xamarin
1
xUnit
5
yaml
1
yolo
1
アプリケーション
1
デザインパターン
1
テスト
1
バッチファイル
2
プログラミング
4
ライセンス
1
暗号資産(仮想通貨)
1
英語
2
確定申告
1
機械学習
1
強化学習
1
雑記
1
書籍
1
数学
1
正規表現
1
Blog Archive
►
2024
(8)
►
4月
(1)
►
3月
(1)
►
2月
(5)
►
1月
(1)
►
2023
(30)
►
12月
(3)
►
11月
(5)
►
10月
(2)
►
9月
(1)
►
8月
(2)
►
7月
(4)
►
6月
(2)
►
5月
(3)
►
4月
(2)
►
3月
(2)
►
2月
(3)
►
1月
(1)
►
2022
(106)
►
12月
(5)
►
11月
(1)
►
10月
(3)
►
9月
(6)
►
8月
(7)
►
7月
(6)
►
6月
(13)
►
5月
(9)
►
4月
(15)
►
3月
(11)
►
2月
(14)
►
1月
(16)
►
2021
(85)
►
12月
(11)
►
11月
(6)
►
10月
(4)
►
9月
(10)
►
8月
(8)
►
7月
(4)
►
6月
(18)
►
5月
(7)
►
4月
(8)
►
3月
(2)
►
2月
(2)
►
1月
(5)
►
2020
(56)
►
12月
(1)
►
11月
(3)
►
10月
(3)
►
9月
(3)
►
8月
(3)
►
7月
(7)
►
6月
(7)
►
5月
(2)
►
4月
(6)
►
3月
(6)
►
2月
(3)
►
1月
(12)
►
2019
(92)
►
12月
(13)
►
11月
(9)
►
10月
(3)
►
9月
(2)
►
8月
(3)
►
7月
(5)
►
6月
(11)
►
5月
(6)
►
4月
(17)
►
3月
(9)
►
2月
(6)
►
1月
(8)
▼
2018
(100)
►
12月
(1)
►
11月
(11)
►
10月
(8)
►
9月
(6)
►
8月
(10)
►
7月
(10)
►
6月
(8)
►
5月
(9)
►
4月
(8)
►
3月
(14)
►
2月
(4)
▼
1月
(11)
Entity Framework Core におけるデータの保存
Moq のインストール
ASP.NET Core で SignalR を使用する
Firefox で英単語を簡単に調べられるアドオン
画像を svg から emf に変換する
Entity Framework Core におけるデータの取得
draw.io で作成した SVG で not supported by viewer と表示される。
dotnet ef コマンドを有効にする
Entity Framework Core におけるリレーションシップについて
Entity Framework Core の基本的な使い方
コマンド "dotnet-ef" に一致する実行可能ファイルが見つかりません
►
2017
(117)
►
12月
(14)
►
11月
(20)
►
10月
(17)
►
9月
(19)
►
8月
(10)
►
7月
(8)
►
6月
(3)
►
5月
(6)
►
4月
(5)
►
3月
(2)
►
2月
(8)
►
1月
(5)
►
2016
(91)
►
12月
(5)
►
11月
(9)
►
10月
(11)
►
9月
(9)
►
8月
(6)
►
7月
(14)
►
6月
(14)
►
5月
(11)
►
4月
(10)
►
3月
(2)
►
2015
(23)
►
12月
(4)
►
11月
(2)
►
10月
(8)
►
9月
(8)
►
7月
(1)
►
2013
(3)
►
11月
(1)
►
9月
(1)
►
7月
(1)
►
2012
(2)
►
7月
(1)
►
6月
(1)
►
2011
(1)
►
9月
(1)
►
2009
(1)
►
7月
(1)
►
2008
(2)
►
11月
(1)
►
7月
(1)
►
2007
(3)
►
10月
(3)