クエリ結果
LINQ to Entities のクエリをコマンド ツリーに変換して実行すると、通常、次のいずれかの形でクエリの結果が返されます。
0 個以上の型指定されたエンティティ オブジェクトのコレクション、または概念モデルの複合型のプロジェクション。
概念モデルでサポートされる CLR 型。
インライン コレクション。
匿名型。
データ ソースに対してクエリを実行すると、その結果は CLR 型に具体化されてクライアントに返されます。 オブジェクトの具体化は、すべて Entity Framework によって実行されます。 Entity Framework と CLR とのマッピングができないことが原因でエラーが発生すると、オブジェクトの具体化中に例外がスローされます。
プリミティブ概念モデル型を返すクエリを実行した場合、その結果は、Entity Framework から切り離されたスタンドアロンの CLR 型で構成されます。 ただし、クエリが ObjectQuery<T> によって表されるエンティティ オブジェクトのコレクションを返す場合、これらの型はオブジェクト コンテキストによって追跡されます。 オブジェクトの動作 (子/親のコレクション、変更の追跡、多態性など) は、すべて Entity Framework で定義されます。 この機能は、Entity Framework で定義されるようにその機能の範囲内で使用されます。 詳しくは、「オブジェクトの使用」をご覧ください。
クエリから返される構造型 (匿名型、NULL 値が許容される複合型など) は、null
値になります。 返されたエンティティの EntityCollection<TEntity> プロパティも null
値になります。 これは、要素を持たない null
に対する FirstOrDefault の呼び出しなど、ObjectQuery<T> 値になっているエンティティのコレクション プロパティが投影されるためです。
場合によっては、特定のクエリで実行中に具体化された結果が生成されることもありますが、クエリはサーバー上で実行され、CLR でエンティティ オブジェクトが具体化されることはありません。 オブジェクトが具体化された場合、その結果に依存すると、問題が発生する可能性があります。
次の例には、MyContact
プロパティがあるカスタム クラス LastName
が含まれています。 LastName
プロパティを設定すると、count
変数が増加します。 次の 2 つのクエリを実行した場合、最初のクエリによって count
が増加しますが、2 つ目のクエリでは増加しません。 これは、ストアでクエリを実行する必要がないため、2 つ目のクエリで結果から LastName
プロパティが投影され、MyContact
クラスが作成されないことが、その理由です。
public static int count = 0;
static void Main(string[] args)
{
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
var query1 = AWEntities
.Contacts
.Where(c => c.LastName == "Jones")
.Select(c => new MyContact { LastName = c.LastName });
// Execute the first query and print the count.
query1.ToList();
Console.WriteLine("Count: " + count);
//Reset the count variable.
count = 0;
var query2 = AWEntities
.Contacts
.Where(c => c.LastName == "Jones")
.Select(c => new MyContact { LastName = c.LastName })
.Select(my => my.LastName);
// Execute the second query and print the count.
query2.ToList();
Console.WriteLine("Count: " + count);
}
Console.WriteLine("Hit enter...");
Console.Read();
}
Public count As Integer = 0
Sub Main()
Using AWEntities As New AdventureWorksEntities()
Dim query1 = AWEntities.Contacts _
.Where(Function(c) c.LastName = "Jones") _
.Select(Function(c) New MyContact With {.LastName = c.LastName})
' Execute the first query and print the count.
query1.ToList()
Console.WriteLine("Count: " & count)
' Reset the count variable.
count = 0
Dim query2 = AWEntities _
.Contacts() _
.Where(Function(c) c.LastName = "Jones") _
.Select(Function(c) New MyContact With {.LastName = c.LastName}) _
.Select(Function(x) x.LastName)
' Execute the second query and print the count.
query2.ToList()
Console.WriteLine("Count: " & count)
End Using
End Sub
public class MyContact
{
String _lastName;
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
count++;
}
}
}
Public Class MyContact
Private _lastName As String
Public Property LastName() As String
Get
Return _lastName
End Get
Set(ByVal value As String)
_lastName = value
count += 1
End Set
End Property
End Class