0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

EntityFrameworkで関連テーブルの要素をソートしたかった話

Posted at

関連テーブルのレコードを複数持つレコードを取得するとき、関連テーブルの要素のソートされた状態で取得したい。

test.cs
var items = ctx.Item
	.Include(x => x.Tags)
	.Where(x => x.Tags.Any())
	.OrderByDescending(x => x.Id);

具体的に言うと上記のTagもソートした状態で取得したい。
しかし、Tagsのどれでソートするという情報をOrderByで書く方法がわからなかった。

test.cs
var items = ctx.Item
	.Include(x => x.Tags)
	.Where(x => x.Tags.Any())
	.OrderByDescending(x => x.Id)
	.ThenBy("Tags.Id"); // Tag.Idでソートをしたいがこういう書き方はできない

1時間くらい調べてみたがどうもできないっぽい?

できないのであればしょうがないので取得後にやるしかない。
しかし、表示部分でソート処理を入れると忘れたとき悲惨なのでこのメソッドチェーンに書いておきたい。

test.cs
var items = ctx.Item
	.Include(x => x.Tags)
	.Where(x => x.Tags.Any())
	.OrderByDescending(x => x.Id)
	.AsEnumerable().Select(x =>
	{
		x.Tags = x.Tags.OrderBy(tag => tag.Id).ToArray();
		return x;
	}).ToArray(); // 無理矢理。。

ちなみに.AsEnumerable()は終端操作ではないので遅延実行はできる。
上記で言うとToArray()で発火。

ただし、AsEnumerable以前のチェーンがクエリ発行の対象になるため、それ以降にWhereとか書いても実行SQLには反映されず、SQL実行後に生成されたIEnumerableへの操作となるため注意しなければならない。

バッドノウハウっぽい記事になってしまった。
もっとスマートなやり方がありそうだが、時間切れ。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?