クエリ結果
LINQ to Entities クエリをコマンド ツリーに変換して実行すると、通常、次のいずれかの形でクエリの結果が返されます。
0 個以上のエンティティ オブジェクトのコレクション、または EDM の複合型の投影。
EDM でサポートされる CLR 型。
インライン コレクション。
匿名型。
データ ソースに対してクエリを実行すると、その結果は CLR 型に具体化されてクライアントに返されます。オブジェクトの具体化は、すべて エンティティ フレームワーク によって実行されます。エンティティ フレームワーク と CLR の間のマッピングができないことが原因でエラーが発生すると、オブジェクトの具体化中に例外がスローされます。
プリミティブ EDM 型を返すクエリを実行した場合、その結果は、スタンドアロンの、エンティティ フレームワーク から切り離された CLR 型から構成されます。ただし、クエリが ObjectQuery によって表されるエンティティ オブジェクトのコレクションを返す場合、これらの型はオブジェクト コンテキストによって追跡されます。オブジェクトの動作 (子/親のコレクション、変更の追跡、多態性など) は、すべて エンティティ フレームワーク で定義されます。この機能は、エンティティ フレームワーク で定義されるようにその機能の範囲内で使用されます。詳細については、「Object Services の概要 (Entity Framework)」を参照してください。
クエリから返される構造型 (匿名型、NULL 値が許容される複合型など) は、null 値になります。返されたエンティティの EntityCollection プロパティも null 値になります。これは、要素を持たない ObjectQuery に対する FirstOrDefault の呼び出しなど、null 値になっているエンティティのコレクション プロパティが投影されるためです。
場合によっては、特定のクエリで実行中に具体化された結果が生成されることもありますが、クエリはサーバー上で実行され、CLR でエンティティ オブジェクトが具体化されることはありません。オブジェクトが具体化された場合、その結果に依存すると、問題が発生する可能性があります。
次の例には、LastName
プロパティがあるカスタム クラス MyContact
が含まれています。LastName
プロパティを設定すると、count
変数が増加します。次の 2 つのクエリを実行した場合、最初のクエリによって count
が増加しますが、2 つ目のクエリでは増加しません。これは、ストアでクエリを実行する必要がないため、2 つ目のクエリで結果から LastName
プロパティが投影され、MyContact
クラスが作成されないことが、その理由です。
Public count As Integer = 0
Sub Main()
Using AWEntities As New AdventureWorksEntities()
Dim query1 = AWEntities.Contact _
.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 _
.Contact() _
.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 static int count = 0;
static void Main(string[] args)
{
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
var query1 = AWEntities
.Contact
.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
.Contact
.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 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
public class MyContact
{
String _lastName;
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
count++;
}
}
}