Object Queries (Entity Framework)
The ObjectQuery generic class represents a query that returns a collection of zero or more typed entity objects. An object query always belongs to an existing object context. This context provides the connection and metadata information that is required to compose and execute the query. A typed ObjectContext includes a set of properties that return typed ObjectQuery instances. There is one of these properties for each entity type in the model. These properties make it easier to create an instance of a typed ObjectQuery. An object query is executed in the following scenarios:
When it is acted upon, such as during a foreach (C#) or For Each (Visual Basic) enumeration.
When it is assigned to fill a List collection.
When the Execute method is explicitly called.
The following query returns a Contact object that has the first and last name specified by the passed parameters:
// Get the contacts with the specified name. ObjectQuery<Contact> contactQuery = context.Contact .Where("it.LastName = @ln AND it.FirstName = @fn", new ObjectParameter("ln", lastName), new ObjectParameter("fn", firstName));
For complete examples of how to use the object context to compose and execute queries, see How to: Execute a Query that Returns an Entity Type (Entity Framework). For more information about Entity SQL queries, see Entity SQL Language.
While object queries are used to return Entity Data Model (EDM) data as entity objects, object queries also support projections that return data that cannot be easily materialized into entity types. ObjectQuery uses the DbDataRecord type for projections that return non-entity types, which can be either nested results or anonymous types. Simple types, such as Int32 or String, are used with projections that return single property values.
The Select query builder method returns an ObjectQuery that, when it is executed, returns a collection of DbDataRecord objects. LINQ to Entities and Entity SQL both support query projection. See the following topics for examples of query projection:
The following considerations apply to query projections:
An ObjectQuery can be initialized so that it represents a single scalar result and not a collection of scalar results. Some extension methods require collection results as input. In this case, an ArgumentException is thrown when one of these methods is called, as in the following example.
// Define a query projection that returns // a single scalar value rather than a collection. ObjectQuery<Int32> scalarQuery = new ObjectQuery<Int32>("100", advWorksContext); // Calling an extension method that requires a collection // will result in an exception. bool hasValues = scalarQuery.Any();
If an ObjectQuery might return a null value when projected to a primitive type, you should use the nullable version of the type. The following query uses a nullable DateTime because the ShipDate property of the SalesOrderHeader object might return a null value.
ObjectQuery<Nullable<DateTime>> shipDateQuery = advWorksContext.SalesOrderHeader .Where("it.CustomerID = @contactId", new ObjectParameter("contactId", contactId)) .SelectValue<Nullable<DateTime>>("it.ShipDate");
Setting the Command Timeout
The default timeout for object queries and the SaveChanges operation is defined by the underlying connection provider. However, you can override this default timeout value by using the CommandTimeout property on the ObjectContext, as shown in the following example.
// Specify a timeout for queries in this context, in seconds. context.CommandTimeout = 120;
Do this when you have a complex query or when other performance issues cause queries or calls to SaveChanges to time out frequently.
Viewing Store Commands
When you query an EDM, the Entity Framework transforms the LINQ to Entities and Entity SQL query based on the EDM into an equivalent query against the data source. Object Services provides the ToTraceString method, which enables you to view these store commands for an ObjectQuery at runtime without having to run a trace against the data source. The EntityClient provider also provides a ToTraceString method on EntityCommand. For more information, see How to: View the Store Commands (Entity Framework).
Retrieving an Object by Its EntityKey
If you know the key value of an entity, you can retrieve it from the data source without explicitly creating and executing an object query. The GetObjectByKey and TryGetObjectByKey methods on ObjectContext will return an object with the specified EntityKey into the object context. When you use GetObjectByKey, you must handle an ObjectNotFoundException when the provided EntityKey does not correspond to an existing entity. For more information, see How to: Return a Specific Object Using its Key (Entity Framework).