EntityFrameworkつかってますかー??
遅いとか言わないで><;
LinqToEntitiesとは
EntityFrameworkを使っているとき、DBアクセス処理をSQLではなくC#上でlinqを書くとSQLに変換して発行してくれる仕組みです。
参考(本家)
https://docs.microsoft.com/ja-jp/dotnet/framework/data/adonet/ef/language-reference/linq-to-entities
DBアクセスが発生するタイミング
LINQ to Entitiesのクエリは遅延実行の為、linqを書いただけではDBにクエリが発行されません
var db = new MyContext();
// このタイミングではDBに対してSELECTしない
var samples = db.Samples.Where(x => x.deleteFlg == 0);
// このタイミングでもDBに対してSELECTしない
samples = samples.Where(x => x.category == "タイプA");
foreachやFor Each ステートメントでクエリ変数を反復処理に使用、または LINQ 変換演算子(ToList、ToArray、ToLookup、ToDictionary など)を使用することで、クエリが即時実行が発生します。
上記の遅延実行とは対照的に、シングルトン値を返すクエリ(Average、Count、First、Max)は即時実行されます
var db = new MyContext();
// このタイミングではDBに対してクエリを発行しない
var query= db.Samples.Where(x => x.deleteFlg == 0);
// このタイミングでもDBに対してクエリを発行しない
query= samples.Where(x => x.category == "タイプA");
// このタイミングでクエリを作成し、DBに対してクエリを発行
sampleList = query.ToList();
参考(本家)
https://docs.microsoft.com/ja-jp/dotnet/framework/data/adonet/ef/language-reference/query-execution
DBに発行したクエリの確認方法
System.Data.Entity.Infrastructure.DbQuery<SampleForLinqToEntities.Models.Model名>query.Sql
でクエリを確認できるようです(デバッグの時に確認できます)(これはバージョンによって違うかも)
たとえばこんな感じ(JOINしている)
SELECT
[Extent1].[WorkId] AS [WorkId],
[Extent1].[UserId] AS [UserId],
[Extent1].[ProcessId] AS [ProcessId],
[Extent2].[UserId] AS [UserId2],
[Extent2].[UserName] AS [UserName],
[Extent2].[CompanyId] AS [CompanyId],
[Extent3].[CompanyId] AS [CompanyId2],
[Extent3].[CompanyName] AS [CompanyName],
FROM [dbo].[Works] AS [Extent1]
INNER JOIN [dbo].[Users] AS [Extent2] ON [Extent1].[UserId] = [Extent2].[UserId2]
INNER JOIN [dbo].[Companies] AS [Extent3] ON [Extent2].[CompanyId] = [Extent3].[CompanyId2]
WHERE ([Extent2].[UserId] = @p__linq__0) AND ([Extent3].[DeleteFlg] = 0)
DBに対して発行されたクエリやタイミングを確認したい場合は、SQLServerの場合はSQLServer Profilerを用いるなどSQL監視ツールを使うとよくわかると思います。こちらも発行されたクエリを確認できます。
良いクエリが発行されるようにlinqをどう書けばよいかはまた次回にでも。。