クエリ結果Query Results

LINQ to Entities クエリをコマンドツリーに変換して実行すると、通常、クエリ結果は次のいずれかとして返されます。After a LINQ to Entities query is converted to command trees and executed, the query results are usually returned as one of the following:

  • 0 個以上の型指定されたエンティティ オブジェクトのコレクション、または概念モデルの複合型のプロジェクション。A collection of zero or more typed entity objects or a projection of complex types in the conceptual model.

  • 概念モデルでサポートされる CLR 型。CLR types supported by the conceptual model.

  • インライン コレクション。Inline collections.

  • 匿名型。Anonymous types.

データ ソースに対してクエリを実行すると、その結果は CLR 型に具体化されてクライアントに返されます。When the query has executed against the data source, the results are materialized into CLR types and returned to the client. オブジェクトの具体化は、すべて Entity Framework によって実行されます。All object materialization is performed by the Entity Framework. Entity Framework と CLR とのマッピングができないことが原因でエラーが発生すると、オブジェクトの具体化中に例外がスローされます。Any errors that result from an inability to map between the Entity Framework and the CLR will cause exceptions to be thrown during object materialization.

クエリ実行でプリミティブ概念モデル型が返された場合、結果は、スタンドアロンで Entity Framework から切断された CLR 型で構成されます。If the query execution returns primitive conceptual model types, the results consist of CLR types that are stand-alone and disconnected from the Entity Framework. ただし、クエリが ObjectQuery<T> によって表されるエンティティ オブジェクトのコレクションを返す場合、これらの型はオブジェクト コンテキストによって追跡されます。However, if the query returns a collection of typed entity objects, represented by ObjectQuery<T>, those types are tracked by the object context. すべてのオブジェクトの動作 (子/親コレクション、変更の追跡、ポリモーフィズムなど) は、Entity Framework で定義されています。All object behavior (such as child/parent collections, change tracking, polymorphism, and so on) are as defined in the Entity Framework. この機能は、Entity Framework で定義されている容量で使用できます。This functionality can be used in its capacity, as defined in the Entity Framework. 詳細については、「オブジェクトの操作」を参照してください。For more information, see Working with Objects.

クエリから返される構造型 (匿名型、NULL 値が許容される複合型など) は、null 値になります。Struct types returned from queries (such as anonymous types and nullable complex types) can be of null value. 返されたエンティティの EntityCollection<TEntity> プロパティも null 値になります。An EntityCollection<TEntity> property of a returned entity can also be of null value. これは、要素を持たない null に対する FirstOrDefault の呼び出しなど、ObjectQuery<T> 値になっているエンティティのコレクション プロパティが投影されるためです。This can result from projecting the collection property of an entity that is of null value, such as calling FirstOrDefault on an ObjectQuery<T> that has no elements.

場合によっては、特定のクエリで実行中に具体化された結果が生成されることもありますが、クエリはサーバー上で実行され、CLR でエンティティ オブジェクトが具体化されることはありません。In certain situations, a query might appear to generate a materialized result during its execution, but the query will be executed on the server and the entity object will never be materialized in the CLR. オブジェクトが具体化された場合、その結果に依存すると、問題が発生する可能性があります。This can cause problems if you are depending on side effects of object materialization.

次の例には、MyContact プロパティがあるカスタム クラス LastName が含まれています。The following example contains a custom class, MyContact, with a LastName property. LastName プロパティを設定すると、count 変数が増加します。When the LastName property is set, a count variable is incremented. 次の 2 つのクエリを実行した場合、最初のクエリによって count が増加しますが、2 つ目のクエリでは増加しません。If you execute the two following queries, the first query will increment count while the second query will not. これは、ストアでクエリを実行する必要がないため、2 つ目のクエリで結果から LastName プロパティが投影され、MyContact クラスが作成されないことが、その理由です。This is because in the second query the LastName property is projected from the results and the MyContact class is never created, because it is not required to execute the query on the store.

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