Sideway
output.to from Sideway
Draft for Information Only

Content

ADO.NET Entity Framework
Entity Framework overview
 Give life to models
 Map objects to data
 Access and change entity data
 Data providers
 Entity data model tools
 Learn more
 See also
Modeling and Mapping
EDM Generator (EdmGen.exe)
 Syntax
 Mode
 Options
 In This Section
 See also
How to: Use EdmGen.exe to Generate the Model and Mapping Files
  To generate the School model for a Visual Basic project using EdmGen.exe
  To generate the School model for a C# project using EdmGen.exe
 See also
How to: Use EdmGen.exe to Generate Object-Layer Code
  To generate object-layer code for the School model for a Visual Basic project using EdmGen.exe
  To generate object-layer code for the School model for a C# project using EdmGen.exe
 See also
How to: Use EdmGen.exe to Validate Model and Mapping Files
  To validate the School model using EdmGen.exe
 See also
How to: Define the Connection String
 To define the Entity Framework connection string
 See also
How to: Make Model and Mapping Files Embedded Resources
  To embed model and mapping files
 Example
 See also
Working with Data Definition Language
 Procedures
  To define a database based on the existing model
Querying a Conceptual Model
Querying Data
Querying and Finding Entities
 Finding entities using a query
 Finding entities using primary keys
  Finding an entity by primary key
  Finding an entity by composite primary key
Loading Related Entities
 Eagerly Loading
  Eagerly loading multiple levels
 Lazy Loading
  Turn lazy loading off for serialization
  Turning off lazy loading for specific navigation properties
  Turn off lazy loading for all entities
 Explicitly Loading
  Applying filters when explicitly loading related entities
 Using Query to count related entities without loading them
No-Tracking Queries
Raw SQL Queries
 Writing SQL queries for entities
  Loading entities from stored procedures
 Writing SQL queries for non-entity types
 Sending raw commands to the database
  Output Parameters
Working with Objects
Working with Objects (Entity Framework)
Working with DbContext
 Defining a DbContext derived class
 Lifetime
 Connections
Working with proxies
 Disabling proxy creation
 Explicitly creating an instance of a proxy
 Getting the actual entity type from a proxy type
Working with entity states
 Entity states and SaveChanges
 Adding a new entity to the context
 Attaching an existing entity to the context
 Attaching an existing but modified entity to the context
 Changing the state of a tracked entity
 Insert or update pattern
Working with property values
 Getting and setting the current or original value of an individual property
 Getting and setting the current value of an unmapped property
 Checking whether a property is marked as modified
 Marking a property as modified
 Reading current, original, and database values for all properties of an entity
 Setting current or original values from another object
 Setting current or original values from a dictionary
 Setting current or original values from a dictionary using Property
 Creating a cloned object containing current, original, or database values
 Getting and setting the current or original values of complex properties
 Using DbPropertyValues to access complex properties
Automatic detect changes
 Disabling automatic detection of changes
Handling Concurrency Conflicts
 Resolving optimistic concurrency exceptions with Reload (database wins)
 Resolving optimistic concurrency exceptions as client wins
 Custom resolution of optimistic concurrency exceptions
 Custom resolution of optimistic concurrency exceptions using objects
Working with Data Providers
 See also
Connection Strings in the ADO.NET Entity Framework
 Connection String Syntax
 Connection String Parameters
 Model and Mapping File Locations
 Support for the |DataDirectory| Substitution String and the Web Application Root Operator (~)
 See also
Entity Framework Data Providers
 In This Section
 Related Sections
 See also
EntityClient Provider for the Entity Framework
 Managing Connections
 Creating Queries
 Executing Queries
 Managing Transactions
 In This Section
 See also
How to: Build an EntityConnection Connection String
  To run the code in this example
 Example
 See also
How to: Execute a Query that Returns PrimitiveType Results
  To run the code in this example
 Example
 See also
How to: Execute a Query that Returns StructuralType Results
  To run the code in this example
 Example
 See also
How to: Execute a Query that Returns RefType Results
  To run the code in this example
 Example
 See also
How to: Execute a Query that Returns Complex Types
  To run the code in this example
 Example
How to: Execute a Query that Returns Nested Collections
  To run the code in this example
 Example
 See also
How to: Execute a Parameterized Entity SQL Query Using EntityCommand
  To run the code in this example
 Example
 See also
How to: Execute a Parameterized Stored Procedure Using EntityCommand
  To run the code in this example
 Example
 See also
How to: Execute a Polymorphic Query
  To run the code in this example
 Example
 See also
How to: Navigate Relationships with the Navigate Operator
  To run the code in this example
 Example
 See also
SqlClient for the Entity Framework
 Provider Schema Attribute
 ProviderManifestToken Schema Attribute
 Provider Namespace Name
 Types
 Functions
 In This Section
 See also
SqlClient for Entity Framework Functions
 In This Section
 See also
Conceptual Model Canonical to SQL Server Functions Mapping
 Date and Time Functions
 Aggregate Functions
 Math functions
 String Functions
 Bitwise Functions
Aggregate Functions (SqlClient for Entity Framework)
 AVG(expression)
 CHECKSUM_AGG(collection)
 COUNT(expression)
 COUNT_BIG(expression)
 MAX(expression)
 MIN(expression)
 STDEV(expression)
 STDEVP(expression)
 SUM(expression)
 VAR(expression)
 VARP(expression)
 See also
Date and Time Functions
 See also
Mathematical Functions
 ABS(expression)
 ACOS(expression)
 ASIN(expression)
 ATAN(expression)
 ATN2(expression, expression)
 CEILING(expression)
 COS(expression)
 COT(expression)
 DEGREES(radians)
 EXP(expression)
 FLOOR(expression)
 LOG(expression)
 LOG10(expression)
 PI()
 POWER(numeric_expression, power_expression)
 RADIANS(expression)
 RAND([seed])
 ROUND(numeric_expression, length[,function])
 SIGN(expression)
 SIN(expression)
 SQRT(expression)
 SQUARE(expression)
 TAN(expression)
 See also
String Functions
 See also
System Functions
 See also
SqlClient for Entity FrameworkTypes
 See also
Known Issues in SqlClient for Entity Framework
 Trailing Spaces in String Functions
 RIGHT Function
 CROSS and OUTER APPLY Operators
 SKIP Operator
 Targeting the Correct SQL Server Version
 Nested Queries in Projection
 Server Generated GUID Identity Values
 See also
Writing an Entity Framework Data Provider
 Introducing the Entity Framework Provider Model
 Sample
 In This Section
 See also
SQL Generation
 The Role of the SQL Generation Module
 In This Section
 See also
The Shape of the Command Trees
 Query Command Trees Overview
 Shapes of the Output Query Command Tree
  Expression Types Not Present in Output Query Command Trees
  Expression Restrictions and Notes
   DbFunctionExpression
   DbNewInstanceExpression
   DbVariableReferenceExpression
   DbGroupByExpression
   DbLimitExpression
   DbScanExpression
  Using Primitive Types
 See also
Generating SQL from Command Trees - Best Practices
 Group DbExpression Nodes in a SQL SELECT Statement
 Flatten Joins in a SQL SELECT Statement
 Input Alias Redirecting
 Join Alias Flattening
 Column Name and Extent Alias Renaming
 Avoid SELECT *
 Reuse of Expressions
 Mapping Primitive Types
 See also
SQL Generation in the Sample Provider
 See also
Architecture and Design
 Data Structures
  ISqlFragment
   SqlBuilder
   SqlSelectStatement
   TopClause
  Symbols
   SymbolPair
   JoinSymbol
   SymbolTable
  Global State for the Visitor
 Common Scenarios
  Grouping Expression Nodes into SQL Statements
  Join Flattening
  Input Alias Redirecting
  Join Alias Flattening
  Column Name and Extent Alias Renaming
 First Phase of the SQL Generation: Visiting the Expression Tree
  Relational (Non-Join) Nodes
  Join Expressions
  Set Operations
  DbScanExpression
  DbVariableReferenceExpression
  DbPropertyExpression
  DbNewInstanceExpression
  DbFunctionExpression
  DbElementExpression
  DbQuantifierExpression
  DbNotExpression
  DbIsEmptyExpression
 Second Phase of SQL Generation: Generating the String Command
 See also
Walkthrough: SQL Generation
 First Phase of SQL Generation: Visiting the Expression Tree
  Second Phase of SQL Generation: Generating the String Command
 See also
Modification SQL Generation
 Overview of Modification Command Trees
  Restrictions on Modification Command Tree Properties
   Returning in DbInsertCommandTree and DbUpdateCommandTree
   SetClauses in DbInsertCommandTree and DbUpdateCommandTree
   Predicate in DbUpdateCommandTree and DbDeleteCommandTree
 Modification SQL Generation in the Sample Provider
  Helper Classes: ExpressionTranslator
  DbComparisonExpression
  DbConstantExpression
  DbPropertyExpression
 Generating an Insert SQL Command
 Generating an Update SQL Command
  Generating a Delete SQL Command
 See also
Provider Manifest Specification
 Requirements
 Scenarios
  Writing a Provider with Symmetric Type Mapping
  Writing a Provider with Asymmetric Type Mapping
 Provider Manifest Discoverability
  Provider Manifest Token
 Provider Manifest Programming Model
  Discoverability API
   Using a Data Store Connection
   Using a Provider Manifest Token
  Provider Manifest Schema
   Types Node
    Type Node
    Namespace Attribute
 See also
Development and Deployment Considerations
 In This Section
 See also
Security Considerations
 General Security Considerations
   Use only trusted data source providers.
   Encrypt your connection to protect sensitive data.
   Secure the connection string.
   Do not expose an EntityConnection to untrusted users.
   Do not pass connections outside the security context.
   Be aware that logon information and passwords may be visible in a memory dump.
   Grant users only the necessary permissions in the data source.
   Run applications with the minimum permissions.
   Do not install untrusted applications.
   Restrict access to all configuration files.
   Restrict permissions to the model and mapping files.
 Security Considerations for Queries
   Prevent SQL injection attacks.
   Prevent very large result sets.
   Avoid Returning IQueryable Results When Exposing Methods to Potentially Untrusted Callers.
 Security Considerations for Entities
   Do not share an ObjectContext across application domains.
   Prevent type safety violations.
   Handle exceptions.
 Security Considerations for ASP.NET Applications
   Verify whether your host performs path checks.
   Do not make assumptions about resolved path names.
   Verify the path length before deployment.
 Security Considerations for ADO.NET Metadata
   Do not expose sensitive information through logging.
   Do not accept MetadataWorkspace objects from untrusted sources.
 See also
Performance Considerations
 Stages of Query Execution
 Additional Considerations
  Query Execution
   Deferred versus immediate execution
   Client-side execution of LINQ queries
  Query and Mapping Complexity
   Mapping complexity
   Query complexity
   Relationships
  Query Paths
   Using query paths
   Explicitly loading related objects
  Saving Changes
  Distributed Transactions
 Strategies for Improving Performance
   Pre-generate views
   Consider using the NoTracking merge option for queries
   Return the correct amount of data
   Limit the scope of the ObjectContext
   Consider opening the database connection manually
 Performance Data
 See also
Deployment Considerations
 See also
Entity Framework Resources
 See also
Entity Framework Terminology
 See also
Getting Started
 See also
Getting Started with the Entity Framework
 See Also
   Concepts
   Other Resources
Get started with Entity Framework 6
 Fundamentals
 Code First resources
 EF Designer resources
 Other resources
Entity SQL Language Reference
 In This Section
 Related Sections
 See also
LINQ to Entities
 Constructing an ObjectQuery Instance
 Composing the Queries
 Query Conversion
 Query Execution
 Materialization
 In This Section
 See also
Queries in LINQ to Entities
 Query Syntax
  Query Expression Syntax
  Method-Based Query Syntax
 See also
Method-Based Query Syntax Examples: Projection
 Select
  Example
  Example
 SelectMany
  Example
  Example
 See also
Method-Based Query Syntax Examples: Filtering
 Where
  Example
  Example
  Example
  Example
 Where…Contains
  Example
  Example
 See also
Method-Based Query Syntax Examples: Ordering
 ThenBy
  Example
 ThenByDescending
  Example
 See also
Method-Based Query Syntax Examples: Aggregate Operators
 Average
  Example
  Example
  Example
  Example
  Example
 Count
  Example
  Example
  Example
 LongCount
  Example
 Max
  Example
  Example
  Example
 Min
  Example
  Example
  Example
 Sum
  Example
  Example
 See also
Method-Based Query Syntax Examples: Partitioning
 Skip
  Example
  Example
 Take
  Example
  Example
 See also
Method-Based Query Syntax Examples: Conversion
 ToArray
  Example
 ToDictionary
  Example
 ToList
  Example
 See also
Method-Based Query Syntax Examples: Join Operators
 GroupJoin
  Example
  Example
 Join
  Example
  Example
 See also
Method-Based Query Syntax Examples: Element Operators
 First
  Example
 See also
Method-Based Query Syntax Examples: Grouping
 Example
 Example
 Example
 See also
Method-Based Query Syntax Examples: Navigating Relationships
 Example
 Example
 Example
 Example
 Example
 See also
Query Expression Syntax Examples: Projection
 Select
  Example
  Example
  Example
 From … From … (SelectMany)
  Example
  Example
  Example
 See also
Query Expression Syntax Examples: Filtering
 Where
  Example
  Example
  Example
  Example
 Where…Contains
  Example
  Example
 See also
Query Expression Syntax Examples: Ordering
 OrderBy
  Example
  Example
 OrderByDescending
  Example
 ThenBy
  Example
 ThenByDescending
  Example
 See also
Query Expression Syntax Examples: Aggregate Operators
 Average
  Example
  Example
  Example
 Count
  Example
  Example
 Max
  Example
  Example
 Min
  Example
  Example
 Sum
  Example
 See also
Query Expression Syntax Examples: Partitioning
 Skip
  Example
 Take
  Example
 See also
Query Expression Syntax Examples: Join Operators
 GroupJoin
  Example
  Example
 Join
  Example
 See also
Query Expression Syntax Examples: Element Operators
 First
  Example
 See also
Query Expression Syntax Examples: Grouping
 Example
 Example
 Example
 See also
Query Expression Syntax Examples: Navigating Relationships
 Example
 Example
 Example
  Example
 See also
Expressions in LINQ to Entities Queries
 In This Section
 See also
Constant Expressions
 See also
Comparison Expressions
 See also
Null Comparisons
 Key Selectors
 Null Property on a Null Object
 Passing Null Collections to Aggregate Functions
 See also
Initialization Expressions
 See also
Calling Functions in LINQ to Entities Queries
 In This Section
 See also
How to: Call Canonical Functions
 Example
 Example
 See also
How to: Call Database Functions
 Example
 Example
 See also
How to: Call Custom Database Functions
  To call custom functions that are defined in the database
 Example
 Example
 Example
 Example
 See also
How to: Call Model-Defined Functions in Queries
  To call a function defined in the conceptual model
 Example
 Example
 Example
 See also
How to: Call Model-Defined Functions as Object Methods
  To call a model-defined function as a method on an ObjectContext object
  To call a model-defined function as static method on a custom class
 Example
 Example
 Example
 Example
 Example
 Example
 Example
 Example
 Example
 See also
Compiled Queries (LINQ to Entities)
 Example
 Example
 Example
 Example
 Example
 Example
 Example
 See also
Query Execution
 Deferred query execution
 Immediate Query Execution
 Store Execution
  Literals and Parameters
  Casting Literals on the Client
  Constructors for Literals
 Store Exceptions
 Store Configuration
Query Results
Standard Query Operators in LINQ to Entities Queries
 Projection and Filtering Methods
 Join Methods
 Set Methods
 Ordering Methods
 Grouping Methods
 Aggregate Methods
 Type Methods
 Paging Methods
 See also
CLR Method to Canonical Function Mapping
 System.String Method (Static) Mapping
 System.String Method (Instance) Mapping
 System.DateTime Method (Static) Mapping
 System.DateTime Method (Instance) Mapping
 System.DateTimeOffset Method (Instance) Mapping
 System.DateTimeOffset Method (Static) Mapping
 System.TimeSpan Method (Instance) Mapping
  DatePart Function
 Mathematical Function Mapping
 Bitwise Operator Mapping
 Other Mapping
 See also
Supported and Unsupported LINQ Methods
 Projection and Restriction Methods
 Join Methods
 Set Methods
 Ordering Methods
 Grouping Methods
 Aggregate Methods
 Type Methods
 Paging Methods
 See also
Known Issues and Considerations in LINQ to Entities
 LINQ Queries That cannot be Cached
 Ordering Information Lost
 Unsigned Integers Not Supported
 Type Conversion Errors
 Referencing Non-Scalar Variables Not Supported
 Nested Queries May Fail with SQL Server 2000
 Projecting to an Anonymous Type
 See also
Entity SQL Language
 Using Entity SQL with the EntityClient provider
 Using Entity SQL with object queries
 In This Section
 See also
Entity SQL Overview
 In This Section
 See also
How Entity SQL Differs from Transact-SQL
 Inheritance and Relationships Support
 Support for Collections
 Support for Expressions
 Uniform Treatment of Subqueries
  Avoiding Implicit Coercions for Subqueries
 Select Value: Avoiding the Implicit Row Wrapper
 Left Correlation and Aliasing
 Referencing Columns (Properties) of Tables (Collections)
 Navigation Through Objects
 No Support for *
 Changes to Group By
 Collection-Based Aggregates
 ORDER BY Clause Usage
 Identifiers
 Transact-SQL Functionality Not Available in Entity SQL
 See also
Entity SQL Quick Reference
 Literals
  String
  DateTime
  Integer
  Other
 Type Constructors
  ROW
  MULTISET
  Object
 References
  REF
  DEREF
  CREATEREF AND KEY
 Functions
  Canonical
  Microsoft Provider-Specific
 Namespaces
 Paging
 Grouping
 Navigation
 SELECT VALUE AND SELECT
  SELECT VALUE
  SELECT
 CASE EXPRESSION
 See also
Type System (Entity SQL)
 Rows
 Collections
 References
 See also
Type Definitions (Entity SQL)
 Remarks
 Examples
 See also
Constructing Types (Entity SQL)
 Row Constructors
 Collection Constructors
 Named Type Constructors (NamedType Initializers)
 See also
Query Plan Caching (Entity SQL)
 Configuration
 Recommended Practice
 See also
Namespaces (Entity SQL)
 Name Resolution Rules
 Differences from the .NET Framework
 ADO.NET Usage
 See also
Identifiers (Entity SQL)
 Simple Identifiers
 Quoted Identifiers
 Aliasing Rules
  Valid Aliases
  Alias Generation
 Scoping Rules
  Query Expressions
  Aggregate Handling
 See also
Parameters (Entity SQL)
 Example
 See also
Variables (Entity SQL)
 Variable
 See also
Unsupported expressions
 Quantified predicates
 * operator
 See also
Literals (Entity SQL)
 Null
 Boolean
 Integer
 Decimal
 Float, Double
 String
 DateTime
 Time
 DateTimeOffset
 Binary
 Guid
 See also
Null Literals and Type Inference (Entity SQL)
 Typed Nulls
 Free-Floating Null Literals
 See also
Input Character Set (Entity SQL)
 See also
Query Expressions (Entity SQL)
 Clauses
 Scope
 See also
Functions (Entity SQL)
 In This Section
 See also
User-Defined Functions (Entity SQL)
 See also
Function Overload Resolution (Entity SQL)
 See also
Aggregate Functions (Entity SQL)
 Collection Functions
 Group Aggregates
 See also
Operator Precedence (Entity SQL)
 See also
Paging (Entity SQL)
 TOP Overview
 SKIP And LIMIT Overview
 See also
Comparison Semantics (Entity SQL)
 Explicit comparison
 Explicit distinction
 Implicit distinction
 Supported Combinations
 See also
Composing Nested Entity SQL Queries
 Nested Expressions
 Nested Queries in Projection
 Ordering Nested Queries
 See also
Nullable Structured Types (Entity SQL)
 Kinds of Nullable Structured Types
 Code Patterns that Produce Null Instances of Structured Types
 See also
Entity SQL reference
 Arithmetic operators
 Canonical functions
 Comparison operators
 Logical and case expression operators
 Query operators
 Reference operators
 Set operators
 Type operators
 Other operators
 See also
+ (Add)
 Syntax
 Arguments
 Result Types
 Remarks
 Example
 See also
+ (String Concatenation) (Entity SQL)
 Syntax
 Arguments
 Result Types
 Example
 See also
- (Negative) (Entity SQL)
 Syntax
 Arguments
 Result Types
 Remarks
 Example
 See also
- (Subtract) (Entity SQL)
 Syntax
 Arguments
 Result Types
 Example
 See also
* (Multiply) (Entity SQL)
 Syntax
 Arguments
 Result Types
 Example
 See also
/ (Divide) (Entity SQL)
 Syntax
 Arguments
 Result Types
 Example
 See also
(Modulo) (Entity SQL)
 Syntax
 Arguments
 Result Types
 Example
 See also
&& (AND) (Entity SQL)
 Syntax
 Arguments
 Remarks
 Example
 See also
|| (OR) (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
! (NOT) (Entity SQL)
 Syntax
 Arguments
 Remarks
 Example
 See also
= (Equals) (Entity SQL)
 Syntax
 Arguments
 Result Types
 Remarks
 Example
 See also
> (Greater Than) (Entity SQL)
 Syntax
 Arguments
 Result Types
 Example
 See also
>= (Greater Than or Equal To) (Entity SQL)
 Syntax
 Arguments
 Result Types
 Example
 See also
< (Less Than) (Entity SQL)
 Syntax
 Arguments
 Result Types
 Example
 See also
<= (Less Than or Equal To) (Entity SQL)
 Syntax
 Arguments
 Result Types
 Example
 See also
!= (Not Equal To) (Entity SQL)
 Syntax
 Arguments
 Result Types
 Example
 See also
. (Member Access) (Entity SQL)
 Syntax
 Arguments
 Remarks
 See also
-- (Comment) (Entity SQL)
 Syntax
 Arguments
 Example
 See also
ANYELEMENT (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
BETWEEN (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
CASE (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
CAST (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
COLLECTION (Entity SQL)
 Syntax
 Arguments
 Remarks
 Example
 See also
CREATEREF (Entity SQL)
 Syntax
 Arguments
 Remarks
 Example
 See also
DEREF (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
EXCEPT (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
EXISTS (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
FLATTEN (Entity SQL)
 Syntax
 Arguments
 Remarks
 Example
 See also
FROM (Entity SQL)
 Syntax
 Arguments
 Remarks
 FROM Clause Items
  Simple FROM Clause Item
  JOIN FROM Clause Item
   Cross Joins
   Inner Joins
   Left Outer Joins and Right Outer Joins
   Full Outer Joins
  APPLY Clause Item
 Multiple Collections in the FROM Clause
 Left Correlation
 Semantics
 Pulling Up Keys from Nested Queries
 See also
FUNCTION (Entity SQL)
 Syntax
 Arguments
 Remarks
 Example
 Example
 See also
GROUP BY (Entity SQL)
 Syntax
 Arguments
 Remarks
 Example
 See also
GROUPPARTITION (Entity SQL)
 Syntax
 Arguments
 Remarks
 Example
HAVING (Entity SQL)
 Syntax
 Arguments
 Remarks
 Example
 See also
KEY (Entity SQL)
 Syntax
 Remarks
 Example
 See also
IN (Entity SQL)
 Syntax
 Arguments
 Return Value
 Example
 See also
INTERSECT (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
ISNULL (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
ISOF (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
LIKE (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
  Escape
 Example
 See also
LIMIT (Entity SQL)
 Syntax
 Arguments
 Example
 See also
MULTISET (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
Named Type Constructor (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
NAVIGATE (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
OFTYPE (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
ORDER BY (Entity SQL)
 Syntax
 Arguments
 Remarks
 Restricted keywords
 Ordering Nested Queries
 Example
 See also
OVERLAPS (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
REF (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
ROW (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
SELECT (Entity SQL)
 Syntax
 Arguments
 Remarks
 Row and Value Select Clauses
 All and Distinct Modifiers
 Differences from Transact-SQL
 Example
 See also
SET (Entity SQL)
 Syntax
 Arguments
 Remarks
 Example
 See also
SKIP (Entity SQL)
 Syntax
 Arguments
 Remarks
 See also
THEN (Entity SQL)
 Syntax
 Arguments
 Remarks
 Example
 See also
TOP (Entity SQL)
 Syntax
 Arguments
 Remarks
 Example
 See also
TREAT (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
UNION (Entity SQL)
 Syntax
 Arguments
 Return Value
 Remarks
 Example
 See also
USING (Entity SQL)
 Syntax
 Arguments
 Example
 See also
WHERE (Entity SQL)
 Syntax
 Arguments
 Remarks
 See also
Canonical Functions
 Canonical Functions Namespace
 In This Section
 See also
Aggregate Canonical Functions
 Aggregate Entity SQL canonical functions
  Avg(expression)
  BigCount(expression)
  Count(expression)
  Max(expression)
  Min(expression)
  StDev(expression)
  StDevP(expression)
  Sum(expression)
  Var(expression)
  VarP(expression)
 Collection-based aggregates
 Group-based aggregates
 See also
Math Canonical Functions
 Abs(value)
 Ceiling(value)
 Floor(value)
 Power(value, exponent)
 Round(value)
 Round(value, digits)
 Truncate(value, digits)
 See also
String Canonical Functions
 Remarks
 See also
Date and Time Canonical Functions
 Remarks
 See also
Bitwise Canonical Functions
 Remarks
 See also
Spatial Functions
Other Canonical Functions
 See also
 Source/Reference

ADO.NET Entity Framework

The docs.microsoft.com/ef/ site is now the main location for the Entity Framework content.

The content for this topic is now available on the following page: Introducing Entity Framework.

Entity Framework overview

The Entity Framework is a set of technologies in ADO.NET that support the development of data-oriented software applications. Architects and developers of data-oriented applications have struggled with the need to achieve two very different objectives. They must model the entities, relationships, and logic of the business problems they are solving, and they must also work with the data engines used to store and retrieve the data. The data may span multiple storage systems, each with its own protocols; even applications that work with a single storage system must balance the requirements of the storage system against the requirements of writing efficient and maintainable application code.

The Entity Framework enables developers to work with data in the form of domain-specific objects and properties, such as customers and customer addresses, without having to concern themselves with the underlying database tables and columns where this data is stored. With the Entity Framework, developers can work at a higher level of abstraction when they deal with data, and can create and maintain data-oriented applications with less code than in traditional applications. Because the Entity Framework is a component of the .NET Framework, Entity Framework applications can run on any computer on which the .NET Framework starting with version 3.5 SP1 is installed.

Give life to models

A longstanding and common design approach when building an application or service is the division of the application or service into three parts: a domain model, a logical model, and a physical model. The domain model defines the entities and relationships in the system that is being modeled. The logical model for a relational database normalizes the entities and relationships into tables with foreign key constraints. The physical model addresses the capabilities of a particular data engine by specifying storage details such as partitioning and indexing.

The physical model is refined by database administrators to improve performance, but programmers writing application code primarily confine themselves to working with the logical model by writing SQL queries and calling stored procedures. Domain models are generally used as a tool for capturing and communicating the requirements of an application, frequently as inert diagrams that are viewed and discussed in the early stages of a project and then abandoned. Many development teams skip creating a conceptual model and begin by specifying tables, columns, and keys in a relational database.

The Entity Framework gives life to models by enabling developers to query entities and relationships in the domain model (called a conceptual model in the Entity Framework) while relying on the Entity Framework to translate those operations to data source–specific commands. This frees applications from hard-coded dependencies on a particular data source.

When working with Code First, the conceptual model is mapped to the storage model in code. The Entity Framework can infer the conceptual model based on the object types and additional configurations that you define. The mapping metadata is generated during run time based on a combination of how you defined your domain types and additional configuration information that you provide in code. Entity Framework generates the database as needed based on the metadata. For more information, see Creating and Mapping a Conceptual Model.

When working with the Entity Data Model Tools, the conceptual model, the storage model, and the mappings between the two are expressed in XML-based schemas and defined in files that have corresponding name extensions:

  • Conceptual schema definition language (CSDL) defines the conceptual model. CSDL is the Entity Framework's implementation of the Entity Data Model. The file extension is .csdl.

  • Store schema definition language (SSDL) defines the storage model, which is also called the logical model. The file extension is .ssdl.

  • Mapping specification language (MSL) defines the mappings between the storage and conceptual models. The file extension is .msl.

The storage model and mappings can change as needed without requiring changes to the conceptual model, data classes, or application code. Because storage models are provider-specific, you can work with a consistent conceptual model across various data sources.

The Entity Framework uses these model and mapping files to create, read, update, and delete operations against entities and relationships in the conceptual model to equivalent operations in the data source. The Entity Framework even supports mapping entities in the conceptual model to stored procedures in the data source. For more information, see CSDL, SSDL, and MSL Specifications.

Map objects to data

Object-oriented programming poses a challenge for interacting with data storage systems. Although the organization of classes frequently mirrors the organization of relational database tables, the fit is not perfect. Multiple normalized tables frequently correspond to a single class, and relationships between classes are often represented differently than relationships between tables are represented. For example, to represent the customer for a sales order, an Order class might use a property that contains a reference to an instance of a Customer class, while an Order table row in a database contains a foreign key column (or set of columns) with a value that corresponds to a primary key value in the Customer table. A Customer class might have a property named Orders that contains a collection of instances of the Order class, while the Customer table in a database has no comparable column. The Entity Framework provides developers with the flexibility to represent relationships in this way, or to more closely model relationships as they are represented in the database.

Existing solutions have tried to bridge this gap, which is frequently called an "impedance mismatch", by only mapping object-oriented classes and properties to relational tables and columns. Instead of taking this traditional approach, the Entity Framework maps relational tables, columns, and foreign key constraints in logical models to entities and relationships in conceptual models. This enables greater flexibility both in defining objects and optimizing the logical model. The Entity Data Model tools generate extensible data classes based on the conceptual model. These classes are partial classes that can be extended with additional members that the developer adds. By default, the classes that are generated for a particular conceptual model derive from base classes that provide services for materializing entities as objects and for tracking and saving changes. Developers can use these classes to work with the entities and relationships as objects related by associations. Developers can also customize the classes that are generated for a conceptual model. For more information, see Working with Objects.

Access and change entity data

More than just another object-relational mapping solution, the Entity Framework is fundamentally about enabling applications to access and change data that is represented as entities and relationships in the conceptual model. The Entity Framework uses information in the model and mapping files to translate object queries against entity types represented in the conceptual model into data source-specific queries. Query results are materialized into objects that the Entity Framework manages. The Entity Framework provides the following ways to query a conceptual model and return objects:

  • LINQ to Entities. Provides Language-Integrated Query (LINQ) support for querying entity types that are defined in a conceptual model. For more information, see LINQ to Entities.

  • Entity SQL. A storage-independent dialect of SQL that works directly with entities in the conceptual model and that supports Entity Data Model concepts. Entity SQL is used both with object queries and queries that are executed by using the EntityClient provider. For more information, see Entity SQL Overview.

The Entity Framework includes the EntityClient data provider. This provider manages connections, translates entity queries into data source-specific queries, and returns a data reader that the Entity Framework uses to materialize entity data into objects. When object materialization is not required, the EntityClient provider can also be used like a standard ADO.NET data provider by enabling applications to execute Entity SQL queries and consume the returned read-only data reader. For more information, see EntityClient Provider for the Entity Framework.

The following diagram illustrates the Entity Framework architecture for accessing data:

Entity Framework Architectural Diagram

The Entity Data Model Tools can generate a class derived from System.Data.Objects.ObjectContext or System.Data.Entity.DbContext that represents the entity container in the conceptual model. This object context provides the facilities for tracking changes and managing identities, concurrency, and relationships. This class also exposes a SaveChanges method that writes inserts, updates, and deletes to the data source. Like queries, these changes are either made by commands automatically generated by the system or by stored procedures that are specified by the developer.

Data providers

The EntityClient provider extends the ADO.NET provider model by accessing data in terms of conceptual entities and relationships. It executes queries that use Entity SQL. Entity SQL provides the underlying query language that enables EntityClient to communicate with the database. For more information, see EntityClient Provider for the Entity Framework.

The Entity Framework includes an updated SqlClient Data Provider that supports canonical command trees. For more information, see SqlClient for the Entity Framework.

Entity data model tools

Together with the Entity Framework runtime, Visual Studio includes the mapping and modeling tools. For more information, see Modeling and Mapping.

Learn more

To learn more about the Entity Framework, see:

Getting Started - Provides information about how to get up and running quickly using the Quickstart, which shows how to create a simple Entity Framework application.

Entity Framework Terminology - Defines many of the terms that are introduced by the Entity Data Model and the Entity Framework and that are used in Entity Framework documentation.

Entity Framework Resources - Provides links to conceptual topics and links to external topics and resources for building Entity Framework applications.

See also

Modeling and Mapping

In the Entity Framework, you can define the conceptual model, storage model, and the mapping between the two in the way that best suits your application. The Entity Data Model Tools in Visual Studio allow you to create an .edmx file from a database or a graphical model and then update that file when either the database or model changes.

Starting with the Entity Framework 4.1 you can also create a model programmatically using Code First development. There are two different scenarios for Code First development. In both cases, the developer defines a model by coding .NET Framework class definitions, and then optionally specifies additional mapping or configuration by using Data Annotations or the fluent API.

For more information, see Creating and Mapping a Conceptual Model.

You can also use the EDM Generator, which is included with the .NET Framework. The EdmGen.exe generates the .csdl, .ssdl, and .msl files from an existing data source. You can also manually create the model and mapping content. For more information, see EDM Generator (EdmGen.exe).

EDM Generator (EdmGen.exe)

EdmGen.exe is a command-line tool used for working with Entity Framework model and mapping files. You can use the EdmGen.exe tool to do the following:

The EdmGen.exe tool is installed in the .NET Framework directory. In many cases, this is located in C:\windows\Microsoft.NET\Framework\v4.0. For 64-bit systems, this is located in C:\windows\Microsoft.NET\Framework64\v4.0. You can also access the EdmGen.exe tool from the Visual Studio command prompt (Click Start, point to All Programs, point to Microsoft Visual Studio 2010, point to Visual Studio Tools, and then click Visual Studio 2010 Command Prompt).

Syntax

EdmGen /mode:choice [options]

Mode

When using the EdmGen.exe tool, you must specify one of the following modes.

Mode Description
/mode:ValidateArtifacts Validates the .csdl, .ssdl, and .msl files and displays any errors or warnings.

This option requires at least one of the /inssdl or /incsdl arguments. If /inmsl is specified, the /inssdl and /incsdl arguments are also required.
/mode:FullGeneration Uses the database connection information specified in the /connectionstring option and generates .csdl, .ssdl, .msl, object layer, and view files.

This option requires a /connectionstring argument and either a /project argument or /outssdl, /outcsdl, /outmsdl, /outobjectlayer, /outviews, /namespace, and /entitycontainer arguments.
/mode:FromSSDLGeneration Generates .csdl and .msl files, source code, and views from the specified .ssdl file.

This option requires the /inssdl argument and either a /project argument or the /outcsdl, /outmsl, /outobjectlayer, /outviews, /namespace, and /entitycontainer arguments.
/mode:EntityClassGeneration Creates a source code file that contains the classes generated from the .csdl file.

This option requires the /incsdl argument and either the /project argument or the /outobjectlayer argument. The /language argument is optional.
/mode:ViewGeneration Creates a source code file that contains the views generated from the .csdl, .ssdl, and .msl files.

This option requires the /inssdl, /incsdl, /inmsl, and either the /project or /outviews arguments. The /language argument is optional.

Options

Option Description
/p[roject]:<string> Specifies the project name to use. The project name is used as a default for the namespace setting, the name of the model and mapping files, the name of object source file, and the name of view generation source file. The entity container name is set to <project>Context.
/prov[ider]:<string> The name of the .NET Framework data provider to be used to generate the storage model (.ssdl) file. The default provider is the .NET Framework Data Provider for SQL Server (System.Data.SqlClient).
/c[onnectionstring]:<connection string> Specifies the string that is used to connect to the data source.
/incsdl:<file> Specifies the .csdl file or a directory where the .csdl files are located. This argument can be specified multiple times so that you can specify several directories or .csdl files. Specifying multiple directories can be useful for generating classes (/mode:EntityClassGeneration) or views (/mode:ViewGeneration) when the conceptual model is split across several files. This can also be useful when you want to validate multiple models (/mode:ValidateArtifacts).
/refcsdl:<file> Specifies the additional .csdl file or files used to resolve any references in the source .csdl file. (The source .csdl file is, the file specified by the /incsdl option). The /refcsdl file contains types that the source .csdl file is dependent upon. This argument can be specified multiple times.
/inmsl:<file> Specifies the .msl file or a directory where the .msl files are located. This argument can be specified multiple times so that you can specify several directories or .msl files. Specifying multiple directories can be useful for generating views (/mode:ViewGeneration) when the conceptual model is split across several files. This can also be useful when you want to validate multiple models (/mode:ValidateArtifacts).
/inssdl:<file> Specifies the .ssdl file or a directory where the .ssdl file is located. This argument can be specified multiple times so that you can specify several directories or .ssdl files. This can be useful when you want to validate multiple models (/mode:ValidateArtifacts).
/outcsdl:<file> Specifies the name of the .csdl file that will be created.
/outmsl:<file> Specifies the name of the .msl file that will be created.
/outssdl:<file> Specifies the name of the .ssdl file that will be created.
/outobjectlayer:<file> Specifies the name of the source code file that contains the objects generated from the .csdl file.
/outviews:<file> Specifies the name of the source code file that contains the views that were generated.
/language:[VB|CSharp] Specifies the language for the generated source code files. The language defaults to C#.
/namespace:<string> Specifies the model namespace to use. The namespace is set in the .csdl file when running /mode:FullGeneration or /mode:FromSSDLGeneration. The namespace is not used when running /mode:EntityClassGeneration.
/entitycontainer:<string> Specifies the name to apply to the <EntityContainer> element in the generated model and mapping files.
/pl[uralize] Applies English-language rules for singulars and plurals to Entity, EntitySet, and NavigationProperty names in the conceptual model. This option will perform the following actions:

- Make all EntityType names singular.
- Make all EntitySet names plural.
- For each NavigationProperty that returns at most one entity, make the name singular.
- For each NavigationProperty that returns more than one entity, make the name plural.
/SuppressForeignKeyProperties or /nofk Prevents foreign key columns from being exposed as scalar properties on entity types in the conceptual model.
/help or ? Displays command syntax and options for the tool.
/nologo Suppresses the copyright message from displaying.
/targetversion: <string> The .NET Framework version that will be used to compile the generated code. The supported versions are 4 and 4.5. Defaults to 4.

In This Section

How to: Use EdmGen.exe to Generate the Model and Mapping Files

How to: Use EdmGen.exe to Generate Object-Layer Code

How to: Use EdmGen.exe to Validate Model and Mapping Files

See also

How to: Use EdmGen.exe to Generate the Model and Mapping Files

This topic shows how to use the EDM Generator (EdmGen.exe) tool to generate the following files based on the School database:

  • A conceptual model (a .csdl file).

  • A storage model (a .ssdl file).

  • Mapping between the conceptual and storage models (a .msl file).

  • Object-layer code in Visual Basic or C#.

  • View files.

The EdmGen.exe tool uses /mode:FullGeneration to generate the files listed above. For more information about EdmGen.exe commands, see EDM Generator (EdmGen.exe).

If you use EdmGen.exe to generate the model and mapping files, you still need to configure your Visual Studio project to use the Entity Framework. For more information, see How to: Manually Configure an Entity Framework Project.

Note

A conceptual model generated by EdmGen.exe includes all the objects in the database. If you want to generate a conceptual model that includes only specific objects, use the Entity Data Model Wizard. For more information, see How to: Use the Entity Data Model Wizard.

To generate the School model for a Visual Basic project using EdmGen.exe

  1. Create the School database. For more information, see Creating the School Sample Database.

  2. At the command prompt, execute the following command without line breaks:

  1. "%windir%\Microsoft.NET\Framework\v4.0.30319\edmgen.exe" /mode:fullgeneration   
    /c:"Data Source=%datasourceserver%; Initial Catalog=School; Integrated Security=SSPI"   
    /project:School /entitycontainer:SchoolEntities /namespace:SchoolModel /language:VB  
    

To generate the School model for a C# project using EdmGen.exe

  1. Create the School database. For more information, see Creating the School Sample Database.

  2. At the command prompt, execute the following command without line breaks:

  1. "%windir%\Microsoft.NET\Framework\v4.0.30319\edmgen.exe" /mode:fullgeneration   
    /c:"Data Source=%datasourceserver%; Initial Catalog=School; Integrated Security=SSPI"   
    /project:School /entitycontainer:SchoolEntities /namespace:SchoolModel /language:CSharp  
    

See also

How to: Use EdmGen.exe to Generate Object-Layer Code

This topic shows how to use the EDM Generator (EdmGen.exe) tool to generate object-layer code based on the .csdl file.

To generate object-layer code for the School model for a Visual Basic project using EdmGen.exe

  1. Create the School database. For more information, see Creating the School Sample Database.

  2. Generate the School model or obtain the School.csdl file. For more information, see How to: Use EdmGen.exe to Generate the Model and Mapping Files.

  3. At the command prompt, execute the following command without line breaks:

  1. "%windir%\Microsoft.NET\Framework\v4.0.30319\edmgen.exe" /mode:EntityClassGeneration   
    /incsdl:.\School.csdl /outobjectlayer:.\School.Objects.vb /language:VB  
    

To generate object-layer code for the School model for a C# project using EdmGen.exe

  1. Create the School database. For more information, see Creating the School Sample Database.

  2. Generate the School model or obtain the School.csdl file. For more information, see How to: Use EdmGen.exe to Generate the Model and Mapping Files.

  3. At the command prompt, execute the following command without line breaks:

  1. "%windir%\Microsoft.NET\Framework\v4.0.30319\edmgen.exe" /mode:EntityClassGeneration   
    /incsdl:.\School.csdl /outobjectlayer:.\School.Objects.cs /language:CSharp  
    

See also

How to: Use EdmGen.exe to Validate Model and Mapping Files

This topic shows how to use the EDM Generator (EdmGen.exe) tool to validate the model and mapping files. For more information, see Entity Data Model.

To validate the School model using EdmGen.exe

  1. Create the School database. For more information, see Creating the School Sample Database.

  2. Generate the School model. For more information, see How to: Use EdmGen.exe to Generate the Model and Mapping Files.

  3. At the command prompt, execute the following command without line breaks:

    console
  1. "%windir%\Microsoft.NET\Framework\v4.0.30319\edmgen.exe" /mode:ValidateArtifacts /inssdl:.\School.ssdl /inmsl:.\School.msl /incsdl:.\School.csdl  
    

See also

How to: Define the Connection String

This topic shows how to define the connection string that is used when connecting to a conceptual model. This topic is based on the AdventureWorks Sales conceptual model. The AdventureWorks Sales Model is used throughout the task-related topics in the Entity Framework documentation. This topic assumes that you have already configured the Entity Framework and defined the AdventureWorks Sales Model. For more information, see How to: Manually Define the Model and Mapping Files. The procedures in this topic are also included in How to: Manually Configure an Entity Framework Project.

Note

If you use the Entity Data Model Wizard in a Visual Studio project, it automatically generates an .edmx file and configures the project to use the Entity Framework. For more information, see How to: Use the Entity Data Model Wizard

To define the Entity Framework connection string

  • Open the project's application configuration file (app.config) and add the following connection string:
XML
<connectionStrings>
    <add name="AdventureWorksEntities" 
         connectionString="metadata=.\AdventureWorks.csdl|.\AdventureWorks.ssdl|.\AdventureWorks.msl;
         provider=System.Data.SqlClient;provider connection string='Data Source=localhost;
         Initial Catalog=AdventureWorks;Integrated Security=True;Connection Timeout=60;
         multipleactiveresultsets=true'" providerName="System.Data.EntityClient" />
</connectionStrings>

If your project does not have an application configuration file, you can add one by selecting Add New Item from the Project menu, selecting the General category, selecting Application Configuration File, and then clicking Add.

See also

How to: Make Model and Mapping Files Embedded Resources

The Entity Framework enables you to deploy model and mapping files as embedded resources of an application. The assembly with the embedded model and mapping files must be loaded in the same application domain as the entity connection. For more information, see Connection Strings. By default, the Entity Data Model tools embed the model and mapping files. When you manually define the model and mapping files, use this procedure to ensure that the files are deployed as embedded resources together with an Entity Framework application.

Note

To maintain embedded resources, you must repeat this procedure whenever the model and mapping files are modified.

To embed model and mapping files

  1. In Solution Explorer, select the conceptual (.csdl) file.

  2. In the Properties pane, set Build Action to Embedded Resource.

  3. Repeat steps 1 and 2 for the storage (.ssdl) file and the mapping (.msl) file.

  4. In Solution Explorer, double-click the App.config file and then modify the Metadata parameter in the connectionString attribute based on one of the following formats:

    • Metadata= res://<assemblyFullName>/<resourceName>;

    • Metadata= res://*/<resourceName>;

    • Metadata=res://*;

    For more information, see Connection Strings.

Example

The following connection string references embedded model and mapping files for the AdventureWorks Sales Model. This connection string is stored in the project's App.config file.

See also

Working with Data Definition Language

Starting with the .NET Framework version 4, the Entity Framework supports data definition language (DDL). This allows you to create or delete a database instance based on the connection string and the metadata of the storage (SSDL) model.

The following methods on the ObjectContext use the connection string and the SSDL content to accomplish the following: create or delete the database, check whether the database exists, and view the generated DDL script:

Note

Executing the DDL commands assumes sufficient permissions.

The methods previously listed delegate most of the work to the underlying ADO.NET data provider. It is the provider’s responsibility to ensure that the naming convention used to generate database objects is consistent with conventions used for querying and updates.

The following example shows you how to generate the database based on the existing model. It also adds a new entity object to the object context and then saves it to the database.

Procedures

To define a database based on the existing model

  1. Create a console application.

  2. Add an existing model to your application.

    1. Add an empty model named SchoolModel. To create an empty model, see the How to: Create a New .edmx File topic.

    The SchoolModel.edmx file is added to your project.

    1. Copy the conceptual, storage, and mapping content for the School model from the School Model topic.

    2. Open the SchoolModel.edmx file and paste the content within the edmx:Runtime tags.

  3. Add the following code to your main function. The code initializes the connection string to your database server, views the DDL script, creates the database, adds a new entity to the context, and saves the changes to the database.

    C#
// Initialize the connection string.
String connectionString = "metadata=res://*/School.csdl|res://*/School.ssdl|res://*/School.msl;provider=System.Data.SqlClient;" +
"provider connection string=\"Data Source=.;Initial Catalog=School;Integrated Security=True;MultipleActiveResultSets=True\"";

using (SchoolEntities context = new SchoolEntities(connectionString))
{
    try
    {
        if (context.DatabaseExists())
        {
            // Make sure the database instance is closed.
            context.DeleteDatabase();
        }
        // View the database creation script.
        Console.WriteLine(context.CreateDatabaseScript());
        // Create the new database instance based on the storage (SSDL) section 
        // of the .edmx file.
        context.CreateDatabase();

        // The following code adds a new objects to the context
        // and saves the changes to the database.
        Department dpt = new Department
        {
            Name = "Engineering",
            Budget = 350000.00M,
            StartDate = DateTime.Now
        };

        context.Departments.AddObject(dpt);
        // An entity has a temporary key 
        // until it is saved to the database.
        Console.WriteLine(dpt.EntityKey.IsTemporary);
        context.SaveChanges();
        // The object was saved and the key 
        // is not temporary any more.
        Console.WriteLine(dpt.EntityKey.IsTemporary);

    }
    catch (InvalidOperationException ex)
    {
        Console.WriteLine(ex.InnerException.Message);
    }
    catch (NotSupportedException ex)
    {
        Console.WriteLine(ex.InnerException.Message);
    }
 }

Querying a Conceptual Model

The ADO.NET Entity Framework enables you to query a conceptual model. To query the conceptual model using the latest version of the Entity Framework, see Querying Data.

Querying Data

[This page is specific to the latest version of the Entity Framework. The latest version is available as the 'Entity Framework' NuGet package. For more information, see Entity Framework Releases and Versioning.]

The msdn.com/data/ef is now the main location for the Entity Framework content.

The content for the Querying Data topic is now available on the following pages.

Querying/Finding Entities

Loading Related Entities

No-Tracking Queries

Raw SQL Queries

Querying and Finding Entities

This topic covers the various ways you can query for data using Entity Framework, including LINQ and the Find method. The techniques shown in this topic apply equally to models created with Code First and the EF Designer.

Finding entities using a query

DbSet and IDbSet implement IQueryable and so can be used as the starting point for writing a LINQ query against the database. This is not the appropriate place for an in-depth discussion of LINQ, but here are a couple of simple examples:

C#
using (var context = new BloggingContext())
{
    // Query for all blogs with names starting with B
    var blogs = from b in context.Blogs
                   where b.Name.StartsWith("B")
                   select b;

    // Query for the Blog named ADO.NET Blog
    var blog = context.Blogs
                    .Where(b => b.Name == "ADO.NET Blog")
                    .FirstOrDefault();
}

Note that DbSet and IDbSet always create queries against the database and will always involve a round trip to the database even if the entities returned already exist in the context. A query is executed against the database when:

  • It is enumerated by a foreach (C#) or For Each (Visual Basic) statement.
  • It is enumerated by a collection operation such as ToArray, ToDictionary, or ToList.
  • LINQ operators such as First or Any are specified in the outermost part of the query.
  • The following methods are called: the Load extension method on a DbSet, DbEntityEntry.Reload, and Database.ExecuteSqlCommand.

When results are returned from the database, objects that do not exist in the context are attached to the context. If an object is already in the context, the existing object is returned (the current and original values of the object's properties in the entry are not overwritten with database values).

When you perform a query, entities that have been added to the context but have not yet been saved to the database are not returned as part of the result set. To get the data that is in the context, see Local Data.

If a query returns no rows from the database, the result will be an empty collection, rather than null.

Finding entities using primary keys

The Find method on DbSet uses the primary key value to attempt to find an entity tracked by the context. If the entity is not found in the context then a query will be sent to the database to find the entity there. Null is returned if the entity is not found in the context or in the database.

Find is different from using a query in two significant ways:

  • A round-trip to the database will only be made if the entity with the given key is not found in the context.
  • Find will return entities that are in the Added state. That is, Find will return entities that have been added to the context but have not yet been saved to the database.

Finding an entity by primary key

The following code shows some uses of Find:

C#
using (var context = new BloggingContext())
{
    // Will hit the database
    var blog = context.Blogs.Find(3);

    // Will return the same instance without hitting the database
    var blogAgain = context.Blogs.Find(3);

    context.Blogs.Add(new Blog { Id = -1 });

    // Will find the new blog even though it does not exist in the database
    var newBlog = context.Blogs.Find(-1);

    // Will find a User which has a string primary key
    var user = context.Users.Find("johndoe1987");
}

Finding an entity by composite primary key

Entity Framework allows your entities to have composite keys - that's a key that is made up of more than one property. For example, you could have a BlogSettings entity that represents a users settings for a particular blog. Because a user would only ever have one BlogSettings for each blog you could chose to make the primary key of BlogSettings a combination of BlogId and Username. The following code attempts to find the BlogSettings with BlogId = 3 and Username = "johndoe1987":

C#
using (var context = new BloggingContext())
{
    var settings = context.BlogSettings.Find(3, "johndoe1987");
}

Note that when you have composite keys you need to use ColumnAttribute or the fluent API to specify an ordering for the properties of the composite key. The call to Find must use this order when specifying the values that form the key.

Loading Related Entities

Entity Framework supports three ways to load related data - eager loading, lazy loading and explicit loading. The techniques shown in this topic apply equally to models created with Code First and the EF Designer.

Eagerly Loading

Eager loading is the process whereby a query for one type of entity also loads related entities as part of the query. Eager loading is achieved by use of the Include method. For example, the queries below will load blogs and all the posts related to each blog.

C#
using (var context = new BloggingContext())
{
    // Load all blogs and related posts
    var blogs1 = context.Blogs
                        .Include(b => b.Posts)
                        .ToList();

    // Load one blogs and its related posts
    var blog1 = context.Blogs
                       .Where(b => b.Name == "ADO.NET Blog")
                       .Include(b => b.Posts)
                       .FirstOrDefault();

    // Load all blogs and related posts  
    // using a string to specify the relationship
    var blogs2 = context.Blogs
                        .Include("Posts")
                        .ToList();

    // Load one blog and its related posts  
    // using a string to specify the relationship
    var blog2 = context.Blogs
                       .Where(b => b.Name == "ADO.NET Blog")
                       .Include("Posts")
                       .FirstOrDefault();
}

Note that Include is an extension method in the System.Data.Entity namespace so make sure you are using that namespace.

Eagerly loading multiple levels

It is also possible to eagerly load multiple levels of related entities. The queries below show examples of how to do this for both collection and reference navigation properties.

C#
using (var context = new BloggingContext())
{
    // Load all blogs, all related posts, and all related comments
    var blogs1 = context.Blogs
                        .Include(b => b.Posts.Select(p => p.Comments))
                        .ToList();

    // Load all users, their related profiles, and related avatar
    var users1 = context.Users
                        .Include(u => u.Profile.Avatar)
                        .ToList();

    // Load all blogs, all related posts, and all related comments  
    // using a string to specify the relationships
    var blogs2 = context.Blogs
                        .Include("Posts.Comments")
                        .ToList();

    // Load all users, their related profiles, and related avatar  
    // using a string to specify the relationships
    var users2 = context.Users
                        .Include("Profile.Avatar")
                        .ToList();
}

Note that it is not currently possible to filter which related entities are loaded. Include will always bring in all related entities.

Lazy Loading

Lazy loading is the process whereby an entity or collection of entities is automatically loaded from the database the first time that a property referring to the entity/entities is accessed. When using POCO entity types, lazy loading is achieved by creating instances of derived proxy types and then overriding virtual properties to add the loading hook. For example, when using the Blog entity class defined below, the related Posts will be loaded the first time the Posts navigation property is accessed:

C#
public class Blog
{  
    public int BlogId { get; set; }  
    public string Name { get; set; }  
    public string Url { get; set; }  
    public string Tags { get; set; }  

    public virtual ICollection<Post> Posts { get; set; }  
}

Turn lazy loading off for serialization

Lazy loading and serialization don’t mix well, and if you aren’t careful you can end up querying for your entire database just because lazy loading is enabled. Most serializers work by accessing each property on an instance of a type. Property access triggers lazy loading, so more entities get serialized. On those entities properties are accessed, and even more entities are loaded. It’s a good practice to turn lazy loading off before you serialize an entity. The following sections show how to do this.

Turning off lazy loading for specific navigation properties

Lazy loading of the Posts collection can be turned off by making the Posts property non-virtual:

C#
public class Blog
{  
    public int BlogId { get; set; }  
    public string Name { get; set; }  
    public string Url { get; set; }  
    public string Tags { get; set; }  

    public ICollection<Post> Posts { get; set; }  
}

Loading of the Posts collection can still be achieved using eager loading (see Eagerly Loading above) or the Load method (see Explicitly Loading below).

Turn off lazy loading for all entities

Lazy loading can be turned off for all entities in the context by setting a flag on the Configuration property. For example:

C#
public class BloggingContext : DbContext
{
    public BloggingContext()
    {
        this.Configuration.LazyLoadingEnabled = false;
    }
}

Loading of related entities can still be achieved using eager loading (see Eagerly Loading above) or the Load method (see Explicitly Loading below).

Explicitly Loading

Even with lazy loading disabled it is still possible to lazily load related entities, but it must be done with an explicit call. To do so you use the Load method on the related entity’s entry. For example:

C#
using (var context = new BloggingContext())
{
    var post = context.Posts.Find(2);

    // Load the blog related to a given post
    context.Entry(post).Reference(p => p.Blog).Load();

    // Load the blog related to a given post using a string  
    context.Entry(post).Reference("Blog").Load();

    var blog = context.Blogs.Find(1);

    // Load the posts related to a given blog
    context.Entry(blog).Collection(p => p.Posts).Load();

    // Load the posts related to a given blog  
    // using a string to specify the relationship
    context.Entry(blog).Collection("Posts").Load();
}

Note that the Reference method should be used when an entity has a navigation property to another single entity. On the other hand, the Collection method should be used when an entity has a navigation property to a collection of other entities.

Applying filters when explicitly loading related entities

The Query method provides access to the underlying query that Entity Framework will use when loading related entities. You can then use LINQ to apply filters to the query before executing it with a call to a LINQ extension method such as ToList, Load, etc. The Query method can be used with both reference and collection navigation properties but is most useful for collections where it can be used to load only part of the collection. For example:

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);

    // Load the posts with the 'entity-framework' tag related to a given blog
    context.Entry(blog)
           .Collection(b => b.Posts)
           .Query()
           .Where(p => p.Tags.Contains("entity-framework"))
           .Load();

    // Load the posts with the 'entity-framework' tag related to a given blog  
    // using a string to specify the relationship  
    context.Entry(blog)
           .Collection("Posts")
           .Query()
           .Where(p => p.Tags.Contains("entity-framework"))
           .Load();
}

When using the Query method it is usually best to turn off lazy loading for the navigation property. This is because otherwise the entire collection may get loaded automatically by the lazy loading mechanism either before or after the filtered query has been executed.

Note that while the relationship can be specified as a string instead of a lambda expression, the returned IQueryable is not generic when a string is used and so the Cast method is usually needed before anything useful can be done with it.

Using Query to count related entities without loading them

Sometimes it is useful to know how many entities are related to another entity in the database without actually incurring the cost of loading all those entities. The Query method with the LINQ Count method can be used to do this. For example:

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);

    // Count how many posts the blog has  
    var postCount = context.Entry(blog)
                           .Collection(b => b.Posts)
                           .Query()
                           .Count();
}

No-Tracking Queries

Sometimes you may want to get entities back from a query but not have those entities be tracked by the context. This may result in better performance when querying for large numbers of entities in read-only scenarios. The techniques shown in this topic apply equally to models created with Code First and the EF Designer.

A new extension method AsNoTracking allows any query to be run in this way. For example:

C#
using (var context = new BloggingContext())
{
    // Query for all blogs without tracking them
    var blogs1 = context.Blogs.AsNoTracking();

    // Query for some blogs without tracking them
    var blogs2 = context.Blogs
                        .Where(b => b.Name.Contains(".NET"))
                        .AsNoTracking()
                        .ToList();
}

Raw SQL Queries

Entity Framework allows you to query using LINQ with your entity classes. However, there may be times that you want to run queries using raw SQL directly against the database. This includes calling stored procedures, which can be helpful for Code First models that currently do not support mapping to stored procedures. The techniques shown in this topic apply equally to models created with Code First and the EF Designer.

Writing SQL queries for entities

The SqlQuery method on DbSet allows a raw SQL query to be written that will return entity instances. The returned objects will be tracked by the context just as they would be if they were returned by a LINQ query. For example:

C#
using (var context = new BloggingContext())
{
    var blogs = context.Blogs.SqlQuery("SELECT * FROM dbo.Blogs").ToList();
}

Note that, just as for LINQ queries, the query is not executed until the results are enumerated—in the example above this is done with the call to ToList.

Care should be taken whenever raw SQL queries are written for two reasons. First, the query should be written to ensure that it only returns entities that are really of the requested type. For example, when using features such as inheritance it is easy to write a query that will create entities that are of the wrong CLR type.

Second, some types of raw SQL query expose potential security risks, especially around SQL injection attacks. Make sure that you use parameters in your query in the correct way to guard against such attacks.

Loading entities from stored procedures

You can use DbSet.SqlQuery to load entities from the results of a stored procedure. For example, the following code calls the dbo.GetBlogs procedure in the database:

C#
using (var context = new BloggingContext())
{
    var blogs = context.Blogs.SqlQuery("dbo.GetBlogs").ToList();
}

You can also pass parameters to a stored procedure using the following syntax:

C#
using (var context = new BloggingContext())
{
    var blogId = 1;

    var blogs = context.Blogs.SqlQuery("dbo.GetBlogById @p0", blogId).Single();
}

Writing SQL queries for non-entity types

A SQL query returning instances of any type, including primitive types, can be created using the SqlQuery method on the Database class. For example:

C#
using (var context = new BloggingContext())
{
    var blogNames = context.Database.SqlQuery<string>(
                       "SELECT Name FROM dbo.Blogs").ToList();
}

The results returned from SqlQuery on Database will never be tracked by the context even if the objects are instances of an entity type.

Sending raw commands to the database

Non-query commands can be sent to the database using the ExecuteSqlCommand method on Database. For example:

C#
using (var context = new BloggingContext())
{
    context.Database.ExecuteSqlCommand(
        "UPDATE dbo.Blogs SET Name = 'Another Name' WHERE BlogId = 1");
}

Note that any changes made to data in the database using ExecuteSqlCommand are opaque to the context until entities are loaded or reloaded from the database.

Output Parameters

If output parameters are used, their values will not be available until the results have been read completely. This is due to the underlying behavior of DbDataReader, see Retrieving Data Using a DataReader for more details.

Working with Objects

The Entity Framework enables you to query, insert, update, and delete data, which is expressed as typed common language runtime (CLR) objects that are instances of entity types. The entity types represent the entities defined in the conceptual model. The Entity Framework maps entities and relationships that are defined in a conceptual model to a data source. The Entity Framework provides facilities to do the following: materialize data returned from the data source as objects; track changes that were made to the objects; handle concurrency; propagate object changes back to the data source; and bind objects to controls.

For more information about working with objects in the latest version of the Entity Framework see, Working with Objects.

Working with Objects (Entity Framework)

[This page is specific to the latest version of the Entity Framework. The latest version is available as the 'Entity Framework' NuGet package. For more information, see Entity Framework Releases and Versioning.]

The msdn.com/data/ef is now the main location for the Entity Framework content.

The content for the Working with Object topic is now available on the following pages.

Working with DbContext

Working with Proxies

Add/Attach and Entity State

Working with Property Values

Automatic Detect Changes

Optimistic Concurrency Patterns

Working with DbContext

In order to use Entity Framework to query, insert, update, and delete data using .NET objects, you first need to Create a Model which maps the entities and relationships that are defined in your model to tables in a database.

Once you have a model, the primary class your application interacts with is System.Data.Entity.DbContext (often referred to as the context class). You can use a DbContext associated to a model to:

  • Write and execute queries
  • Materialize query results as entity objects
  • Track changes that are made to those objects
  • Persist object changes back on the database
  • Bind objects in memory to UI controls

This page gives some guidance on how to manage the context class.

Defining a DbContext derived class

The recommended way to work with context is to define a class that derives from DbContext and exposes DbSet properties that represent collections of the specified entities in the context. If you are working with the EF Designer, the context will be generated for you. If you are working with Code First, you will typically write the context yourself.

C#
public class ProductContext : DbContext
{
    public DbSet<Category> Categories { get; set; }
    public DbSet<Product> Products { get; set; }
}

Once you have a context, you would query for, add (using Add or Attach methods ) or remove (using Remove) entities in the context through these properties. Accessing a DbSet property on a context object represent a starting query that returns all entities of the specified type. Note that just accessing a property will not execute the query. A query is executed when:

  • It is enumerated by a foreach (C#) or For Each (Visual Basic) statement.
  • It is enumerated by a collection operation such as ToArray, ToDictionary, or ToList.
  • LINQ operators such as First or Any are specified in the outermost part of the query.
  • One of the following methods are called: the Load extension method, DbEntityEntry.Reload, Database.ExecuteSqlCommand, and DbSet<T>.Find, if an entity with the specified key is not found already loaded in the context.

Lifetime

The lifetime of the context begins when the instance is created and ends when the instance is either disposed or garbage-collected. Use using if you want all the resources that the context controls to be disposed at the end of the block. When you use using, the compiler automatically creates a try/finally block and calls dispose in the finally block.

C#
public void UseProducts()
{
    using (var context = new ProductContext())
    {     
        // Perform data access using the context
    }
}

Here are some general guidelines when deciding on the lifetime of the context:

  • When working with Web applications, use a context instance per request.
  • When working with Windows Presentation Foundation (WPF) or Windows Forms, use a context instance per form. This lets you use change-tracking functionality that context provides.
  • If the context instance is created by a dependency injection container, it is usually the responsibility of the container to dispose the context.
  • If the context is created in application code, remember to dispose of the context when it is no longer required.
  • When working with long-running context consider the following:
    • As you load more objects and their references into memory, the memory consumption of the context may increase rapidly. This may cause performance issues.
    • The context is not thread-safe, therefore it should not be shared across multiple threads doing work on it concurrently.
    • If an exception causes the context to be in an unrecoverable state, the whole application may terminate.
    • The chances of running into concurrency-related issues increase as the gap between the time when the data is queried and updated grows.

Connections

By default, the context manages connections to the database. The context opens and closes connections as needed. For example, the context opens a connection to execute a query, and then closes the connection when all the result sets have been processed.

There are cases when you want to have more control over when the connection opens and closes. For example, when working with SQL Server Compact, it is often recommended to maintain a separate open connection to the database for the lifetime of the application to improve performance. You can manage this process manually by using the Connection property.

Working with proxies

When creating instances of POCO entity types, Entity Framework often creates instances of a dynamically generated derived type that acts as a proxy for the entity. This proxy overrides some virtual properties of the entity to insert hooks for performing actions automatically when the property is accessed. For example, this mechanism is used to support lazy loading of relationships. The techniques shown in this topic apply equally to models created with Code First and the EF Designer.

Disabling proxy creation

Sometimes it is useful to prevent Entity Framework from creating proxy instances. For example, serializing non-proxy instances is considerably easier than serializing proxy instances. Proxy creation can be turned off by clearing the ProxyCreationEnabled flag. One place you could do this is in the constructor of your context. For example:

C#
public class BloggingContext : DbContext
{
    public BloggingContext()
    {
        this.Configuration.ProxyCreationEnabled = false;
    }  

    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
}

Note that the EF will not create proxies for types where there is nothing for the proxy to do. This means that you can also avoid proxies by having types that are sealed and/or have no virtual properties.

Explicitly creating an instance of a proxy

A proxy instance will not be created if you create an instance of an entity using the new operator. This may not be a problem, but if you need to create a proxy instance (for example, so that lazy loading or proxy change tracking will work) then you can do so using the Create method of DbSet. For example:

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Create();
}

The generic version of Create can be used if you want to create an instance of a derived entity type. For example:

C#
using (var context = new BloggingContext())
{
    var admin = context.Users.Create<Administrator>();
}

Note that the Create method does not add or attach the created entity to the context.

Note that the Create method will just create an instance of the entity type itself if creating a proxy type for the entity would have no value because it would not do anything. For example, if the entity type is sealed and/or has no virtual properties then Create will just create an instance of the entity type.

Getting the actual entity type from a proxy type

Proxy types have names that look something like this:

System.Data.Entity.DynamicProxies.Blog_5E43C6C196972BF0754973E48C9C941092D86818CD94005E9A759B70BF6E48E6

You can find the entity type for this proxy type using the GetObjectType method from ObjectContext. For example:

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);
    var entityType = ObjectContext.GetObjectType(blog.GetType());
}

Note that if the type passed to GetObjectType is an instance of an entity type that is not a proxy type then the type of entity is still returned. This means you can always use this method to get the actual entity type without any other checking to see if the type is a proxy type or not.

Working with entity states

This topic will cover how to add and attach entities to a context and how Entity Framework processes these during SaveChanges. Entity Framework takes care of tracking the state of entities while they are connected to a context, but in disconnected or N-Tier scenarios you can let EF know what state your entities should be in. The techniques shown in this topic apply equally to models created with Code First and the EF Designer.

Entity states and SaveChanges

An entity can be in one of five states as defined by the EntityState enumeration. These states are:

  • Added: the entity is being tracked by the context but does not yet exist in the database
  • Unchanged: the entity is being tracked by the context and exists in the database, and its property values have not changed from the values in the database
  • Modified: the entity is being tracked by the context and exists in the database, and some or all of its property values have been modified
  • Deleted: the entity is being tracked by the context and exists in the database, but has been marked for deletion from the database the next time SaveChanges is called
  • Detached: the entity is not being tracked by the context

SaveChanges does different things for entities in different states:

  • Unchanged entities are not touched by SaveChanges. Updates are not sent to the database for entities in the Unchanged state.
  • Added entities are inserted into the database and then become Unchanged when SaveChanges returns.
  • Modified entities are updated in the database and then become Unchanged when SaveChanges returns.
  • Deleted entities are deleted from the database and are then detached from the context.

The following examples show ways in which the state of an entity or an entity graph can be changed.

Adding a new entity to the context

A new entity can be added to the context by calling the Add method on DbSet. This puts the entity into the Added state, meaning that it will be inserted into the database the next time that SaveChanges is called. For example:

C#
using (var context = new BloggingContext())
{
    var blog = new Blog { Name = "ADO.NET Blog" };
    context.Blogs.Add(blog);
    context.SaveChanges();
}

Another way to add a new entity to the context is to change its state to Added. For example:

C#
using (var context = new BloggingContext())
{
    var blog = new Blog { Name = "ADO.NET Blog" };
    context.Entry(blog).State = EntityState.Added;
    context.SaveChanges();
}

Finally, you can add a new entity to the context by hooking it up to another entity that is already being tracked. This could be by adding the new entity to the collection navigation property of another entity or by setting a reference navigation property of another entity to point to the new entity. For example:

C#
using (var context = new BloggingContext())
{
    // Add a new User by setting a reference from a tracked Blog
    var blog = context.Blogs.Find(1);
    blog.Owner = new User { UserName = "johndoe1987" };

    // Add a new Post by adding to the collection of a tracked Blog
    blog.Posts.Add(new Post { Name = "How to Add Entities" });

    context.SaveChanges();
}

Note that for all of these examples if the entity being added has references to other entities that are not yet tracked then these new entities will also be added to the context and will be inserted into the database the next time that SaveChanges is called.

Attaching an existing entity to the context

If you have an entity that you know already exists in the database but which is not currently being tracked by the context then you can tell the context to track the entity using the Attach method on DbSet. The entity will be in the Unchanged state in the context. For example:

C#
var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Blogs.Attach(existingBlog);

    // Do some more work...  

    context.SaveChanges();
}

Note that no changes will be made to the database if SaveChanges is called without doing any other manipulation of the attached entity. This is because the entity is in the Unchanged state.

Another way to attach an existing entity to the context is to change its state to Unchanged. For example:

C#
var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Entry(existingBlog).State = EntityState.Unchanged;

    // Do some more work...  

    context.SaveChanges();
}

Note that for both of these examples if the entity being attached has references to other entities that are not yet tracked then these new entities will also attached to the context in the Unchanged state.

Attaching an existing but modified entity to the context

If you have an entity that you know already exists in the database but to which changes may have been made then you can tell the context to attach the entity and set its state to Modified. For example:

C#
var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Entry(existingBlog).State = EntityState.Modified;

    // Do some more work...  

    context.SaveChanges();
}

When you change the state to Modified all the properties of the entity will be marked as modified and all the property values will be sent to the database when SaveChanges is called.

Note that if the entity being attached has references to other entities that are not yet tracked, then these new entities will attached to the context in the Unchanged state—they will not automatically be made Modified. If you have multiple entities that need to be marked Modified you should set the state for each of these entities individually.

Changing the state of a tracked entity

You can change the state of an entity that is already being tracked by setting the State property on its entry. For example:

C#
var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Blogs.Attach(existingBlog);
    context.Entry(existingBlog).State = EntityState.Unchanged;

    // Do some more work...  

    context.SaveChanges();
}

Note that calling Add or Attach for an entity that is already tracked can also be used to change the entity state. For example, calling Attach for an entity that is currently in the Added state will change its state to Unchanged.

Insert or update pattern

A common pattern for some applications is to either Add an entity as new (resulting in a database insert) or Attach an entity as existing and mark it as modified (resulting in a database update) depending on the value of the primary key. For example, when using database generated integer primary keys it is common to treat an entity with a zero key as new and an entity with a non-zero key as existing. This pattern can be achieved by setting the entity state based on a check of the primary key value. For example:

C#
public void InsertOrUpdate(Blog blog)
{
    using (var context = new BloggingContext())
    {
        context.Entry(blog).State = blog.BlogId == 0 ?
                                   EntityState.Added :
                                   EntityState.Modified;

        context.SaveChanges();
    }
}

Note that when you change the state to Modified all the properties of the entity will be marked as modified and all the property values will be sent to the database when SaveChanges is called.

Working with property values

For the most part Entity Framework will take care of tracking the state, original values, and current values of the properties of your entity instances. However, there may be some cases - such as disconnected scenarios - where you want to view or manipulate the information EF has about the properties. The techniques shown in this topic apply equally to models created with Code First and the EF Designer.

Entity Framework keeps track of two values for each property of a tracked entity. The current value is, as the name indicates, the current value of the property in the entity. The original value is the value that the property had when the entity was queried from the database or attached to the context.

There are two general mechanisms for working with property values:

  • The value of a single property can be obtained in a strongly typed way using the Property method.
  • Values for all properties of an entity can be read into a DbPropertyValues object. DbPropertyValues then acts as a dictionary-like object to allow property values to be read and set. The values in a DbPropertyValues object can be set from values in another DbPropertyValues object or from values in some other object, such as another copy of the entity or a simple data transfer object (DTO).

The sections below show examples of using both of the above mechanisms.

Getting and setting the current or original value of an individual property

The example below shows how the current value of a property can be read and then set to a new value:

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(3);

    // Read the current value of the Name property
    string currentName1 = context.Entry(blog).Property(u => u.Name).CurrentValue;

    // Set the Name property to a new value
    context.Entry(blog).Property(u => u.Name).CurrentValue = "My Fancy Blog";

    // Read the current value of the Name property using a string for the property name
    object currentName2 = context.Entry(blog).Property("Name").CurrentValue;

    // Set the Name property to a new value using a string for the property name
    context.Entry(blog).Property("Name").CurrentValue = "My Boring Blog";
}

Use the OriginalValue property instead of the CurrentValue property to read or set the original value.

Note that the returned value is typed as “object” when a string is used to specify the property name. On the other hand, the returned value is strongly typed if a lambda expression is used.

Setting the property value like this will only mark the property as modified if the new value is different from the old value.

When a property value is set in this way the change is automatically detected even if AutoDetectChanges is turned off.

Getting and setting the current value of an unmapped property

The current value of a property that is not mapped to the database can also be read. An example of an unmapped property could be an RssLink property on Blog. This value may be calculated based on the BlogId, and therefore doesn't need to be stored in the database. For example:

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);
    // Read the current value of an unmapped property
    var rssLink = context.Entry(blog).Property(p => p.RssLink).CurrentValue;

    // Use a string to specify the property name
    var rssLinkAgain = context.Entry(blog).Property("RssLink").CurrentValue;
}

The current value can also be set if the property exposes a setter.

Reading the values of unmapped properties is useful when performing Entity Framework validation of unmapped properties. For the same reason current values can be read and set for properties of entities that are not currently being tracked by the context. For example:

C#
using (var context = new BloggingContext())
{
    // Create an entity that is not being tracked
    var blog = new Blog { Name = "ADO.NET Blog" };

    // Read and set the current value of Name as before
    var currentName1 = context.Entry(blog).Property(u => u.Name).CurrentValue;
    context.Entry(blog).Property(u => u.Name).CurrentValue = "My Fancy Blog";
    var currentName2 = context.Entry(blog).Property("Name").CurrentValue;
    context.Entry(blog).Property("Name").CurrentValue = "My Boring Blog";
}

Note that original values are not available for unmapped properties or for properties of entities that are not being tracked by the context.

Checking whether a property is marked as modified

The example below shows how to check whether or not an individual property is marked as modified:

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);

    var nameIsModified1 = context.Entry(blog).Property(u => u.Name).IsModified;

    // Use a string for the property name
    var nameIsModified2 = context.Entry(blog).Property("Name").IsModified;
}

The values of modified properties are sent as updates to the database when SaveChanges is called.

Marking a property as modified

The example below shows how to force an individual property to be marked as modified:

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);

    context.Entry(blog).Property(u => u.Name).IsModified = true;

    // Use a string for the property name
    context.Entry(blog).Property("Name").IsModified = true;
}

Marking a property as modified forces an update to be send to the database for the property when SaveChanges is called even if the current value of the property is the same as its original value.

It is not currently possible to reset an individual property to be not modified after it has been marked as modified. This is something we plan to support in a future release.

Reading current, original, and database values for all properties of an entity

The example below shows how to read the current values, the original values, and the values actually in the database for all mapped properties of an entity.

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);

    // Make a modification to Name in the tracked entity
    blog.Name = "My Cool Blog";

    // Make a modification to Name in the database
    context.Database.SqlCommand("update dbo.Blogs set Name = 'My Boring Blog' where Id = 1");

    // Print out current, original, and database values
    Console.WriteLine("Current values:");
    PrintValues(context.Entry(blog).CurrentValues);

    Console.WriteLine("\nOriginal values:");
    PrintValues(context.Entry(blog).OriginalValues);

    Console.WriteLine("\nDatabase values:");
    PrintValues(context.Entry(blog).GetDatabaseValues());
}

public static void PrintValues(DbPropertyValues values)
{
    foreach (var propertyName in values.PropertyNames)
    {
        Console.WriteLine("Property {0} has value {1}",
                          propertyName, values[propertyName]);
    }
}

The current values are the values that the properties of the entity currently contain. The original values are the values that were read from the database when the entity was queried. The database values are the values as they are currently stored in the database. Getting the database values is useful when the values in the database may have changed since the entity was queried such as when a concurrent edit to the database has been made by another user.

Setting current or original values from another object

The current or original values of a tracked entity can be updated by copying values from another object. For example:

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);
    var coolBlog = new Blog { Id = 1, Name = "My Cool Blog" };
    var boringBlog = new BlogDto { Id = 1, Name = "My Boring Blog" };

    // Change the current and original values by copying the values from other objects
    var entry = context.Entry(blog);
    entry.CurrentValues.SetValues(coolBlog);
    entry.OriginalValues.SetValues(boringBlog);

    // Print out current and original values
    Console.WriteLine("Current values:");
    PrintValues(entry.CurrentValues);

    Console.WriteLine("\nOriginal values:");
    PrintValues(entry.OriginalValues);
}

public class BlogDto
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Running the code above will print out:

Current values:
Property Id has value 1
Property Name has value My Cool Blog

Original values:
Property Id has value 1
Property Name has value My Boring Blog

This technique is sometimes used when updating an entity with values obtained from a service call or a client in an n-tier application. Note that the object used does not have to be of the same type as the entity so long as it has properties whose names match those of the entity. In the example above, an instance of BlogDTO is used to update the original values.

Note that only properties that are set to different values when copied from the other object will be marked as modified.

Setting current or original values from a dictionary

The current or original values of a tracked entity can be updated by copying values from a dictionary or some other data structure. For example:

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);

    var newValues = new Dictionary\<string, object>
    {
        { "Name", "The New ADO.NET Blog" },
        { "Url", "blogs.msdn.com/adonet" },
    };

    var currentValues = context.Entry(blog).CurrentValues;

    foreach (var propertyName in newValues.Keys)
    {
        currentValues[propertyName] = newValues[propertyName];
    }

    PrintValues(currentValues);
}

Use the OriginalValues property instead of the CurrentValues property to set original values.

Setting current or original values from a dictionary using Property

An alternative to using CurrentValues or OriginalValues as shown above is to use the Property method to set the value of each property. This can be preferable when you need to set the values of complex properties. For example:

C#
using (var context = new BloggingContext())
{
    var user = context.Users.Find("johndoe1987");

    var newValues = new Dictionary\<string, object>
    {
        { "Name", "John Doe" },
        { "Location.City", "Redmond" },
        { "Location.State.Name", "Washington" },
        { "Location.State.Code", "WA" },
    };

    var entry = context.Entry(user);

    foreach (var propertyName in newValues.Keys)
    {
        entry.Property(propertyName).CurrentValue = newValues[propertyName];
    }
}

In the example above complex properties are accessed using dotted names. For other ways to access complex properties see the two sections later in this topic specifically about complex properties.

Creating a cloned object containing current, original, or database values

The DbPropertyValues object returned from CurrentValues, OriginalValues, or GetDatabaseValues can be used to create a clone of the entity. This clone will contain the property values from the DbPropertyValues object used to create it. For example:

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);

    var clonedBlog = context.Entry(blog).GetDatabaseValues().ToObject();
}

Note that the object returned is not the entity and is not being tracked by the context. The returned object also does not have any relationships set to other objects.

The cloned object can be useful for resolving issues related to concurrent updates to the database, especially where a UI that involves data binding to objects of a certain type is being used.

Getting and setting the current or original values of complex properties

The value of an entire complex object can be read and set using the Property method just as it can be for a primitive property. In addition you can drill down into the complex object and read or set properties of that object, or even a nested object. Here are some examples:

C#
using (var context = new BloggingContext())
{
    var user = context.Users.Find("johndoe1987");

    // Get the Location complex object
    var location = context.Entry(user)
                       .Property(u => u.Location)
                       .CurrentValue;

    // Get the nested State complex object using chained calls
    var state1 = context.Entry(user)
                     .ComplexProperty(u => u.Location)
                     .Property(l => l.State)
                     .CurrentValue;

    // Get the nested State complex object using a single lambda expression
    var state2 = context.Entry(user)
                     .Property(u => u.Location.State)
                     .CurrentValue;

    // Get the nested State complex object using a dotted string
    var state3 = context.Entry(user)
                     .Property("Location.State")
                     .CurrentValue;

    // Get the value of the Name property on the nested State complex object using chained calls
    var name1 = context.Entry(user)
                       .ComplexProperty(u => u.Location)
                       .ComplexProperty(l => l.State)
                       .Property(s => s.Name)
                       .CurrentValue;

    // Get the value of the Name property on the nested State complex object using a single lambda expression
    var name2 = context.Entry(user)
                       .Property(u => u.Location.State.Name)
                       .CurrentValue;

    // Get the value of the Name property on the nested State complex object using a dotted string
    var name3 = context.Entry(user)
                       .Property("Location.State.Name")
                       .CurrentValue;
}

Use the OriginalValue property instead of the CurrentValue property to get or set an original value.

Note that either the Property or the ComplexProperty method can be used to access a complex property. However, the ComplexProperty method must be used if you wish to drill down into the complex object with additional Property or ComplexProperty calls.

Using DbPropertyValues to access complex properties

When you use CurrentValues, OriginalValues, or GetDatabaseValues to get all the current, original, or database values for an entity, the values of any complex properties are returned as nested DbPropertyValues objects. These nested objects can then be used to get values of the complex object. For example, the following method will print out the values of all properties, including values of any complex properties and nested complex properties.

C#
public static void WritePropertyValues(string parentPropertyName, DbPropertyValues propertyValues)
{
    foreach (var propertyName in propertyValues.PropertyNames)
    {
        var nestedValues = propertyValues[propertyName] as DbPropertyValues;
        if (nestedValues != null)
        {
            WritePropertyValues(parentPropertyName + propertyName + ".", nestedValues);
        }
        else
        {
            Console.WriteLine("Property {0}{1} has value {2}",
                              parentPropertyName, propertyName,
                              propertyValues[propertyName]);
        }
    }
}

To print out all current property values the method would be called like this:

C#
using (var context = new BloggingContext())
{
    var user = context.Users.Find("johndoe1987");

    WritePropertyValues("", context.Entry(user).CurrentValues);
}

Automatic detect changes

When using most POCO entities the determination of how an entity has changed (and therefore which updates need to be sent to the database) is handled by the Detect Changes algorithm. Detect Changes works by detecting the differences between the current property values of the entity and the original property values that are stored in a snapshot when the entity was queried or attached. The techniques shown in this topic apply equally to models created with Code First and the EF Designer.

By default, Entity Framework performs Detect Changes automatically when the following methods are called:

  • DbSet.Find
  • DbSet.Local
  • DbSet.Add
  • DbSet.AddRange
  • DbSet.Remove
  • DbSet.RemoveRange
  • DbSet.Attach
  • DbContext.SaveChanges
  • DbContext.GetValidationErrors
  • DbContext.Entry
  • DbChangeTracker.Entries

Disabling automatic detection of changes

If you are tracking a lot of entities in your context and you call one of these methods many times in a loop, then you may get significant performance improvements by turning off detection of changes for the duration of the loop. For example:

C#
using (var context = new BloggingContext())
{
    try
    {
        context.Configuration.AutoDetectChangesEnabled = false;

        // Make many calls in a loop
        foreach (var blog in aLotOfBlogs)
        {
            context.Blogs.Add(blog);
        }
    }
    finally
    {
        context.Configuration.AutoDetectChangesEnabled = true;
    }
}

Don’t forget to re-enable detection of changes after the loop — We've used a try/finally to ensure it is always re-enabled even if code in the loop throws an exception.

An alternative to disabling and re-enabling is to leave automatic detection of changes turned off at all times and either call context.ChangeTracker.DetectChanges explicitly or use change tracking proxies diligently. Both of these options are advanced and can easily introduce subtle bugs into your application so use them with care.

If you need to add or remove many objects from a context, consider using DbSet.AddRange and DbSet.RemoveRange. This methods automatically detect changes only once after the add or remove operations are completed.

Handling Concurrency Conflicts

Optimistic concurrency involves optimistically attempting to save your entity to the database in the hope that the data there has not changed since the entity was loaded. If it turns out that the data has changed then an exception is thrown and you must resolve the conflict before attempting to save again. This topic covers how to handle such exceptions in Entity Framework. The techniques shown in this topic apply equally to models created with Code First and the EF Designer.

This post is not the appropriate place for a full discussion of optimistic concurrency. The sections below assume some knowledge of concurrency resolution and show patterns for common tasks.

Many of these patterns make use of the topics discussed in Working with Property Values.

Resolving concurrency issues when you are using independent associations (where the foreign key is not mapped to a property in your entity) is much more difficult than when you are using foreign key associations. Therefore if you are going to do concurrency resolution in your application it is advised that you always map foreign keys into your entities. All the examples below assume that you are using foreign key associations.

A DbUpdateConcurrencyException is thrown by SaveChanges when an optimistic concurrency exception is detected while attempting to save an entity that uses foreign key associations.

Resolving optimistic concurrency exceptions with Reload (database wins)

The Reload method can be used to overwrite the current values of the entity with the values now in the database. The entity is then typically given back to the user in some form and they must try to make their changes again and re-save. For example:

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);
    blog.Name = "The New ADO.NET Blog";

    bool saveFailed;
    do
    {
        saveFailed = false;

        try
        {
            context.SaveChanges();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            saveFailed = true;

            // Update the values of the entity that failed to save from the store
            ex.Entries.Single().Reload();
        }

    } while (saveFailed);
}

A good way to simulate a concurrency exception is to set a breakpoint on the SaveChanges call and then modify an entity that is being saved in the database using another tool such as SQL Management Studio. You could also insert a line before SaveChanges to update the database directly using SqlCommand. For example:

C#
context.Database.SqlCommand(
    "UPDATE dbo.Blogs SET Name = 'Another Name' WHERE BlogId = 1");

The Entries method on DbUpdateConcurrencyException returns the DbEntityEntry instances for the entities that failed to update. (This property currently always returns a single value for concurrency issues. It may return multiple values for general update exceptions.) An alternative for some situations might be to get entries for all entities that may need to be reloaded from the database and call reload for each of these.

Resolving optimistic concurrency exceptions as client wins

The example above that uses Reload is sometimes called database wins or store wins because the values in the entity are overwritten by values from the database. Sometimes you may wish to do the opposite and overwrite the values in the database with the values currently in the entity. This is sometimes called client wins and can be done by getting the current database values and setting them as the original values for the entity. (See Working with Property Values for information on current and original values.) For example:

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);
    blog.Name = "The New ADO.NET Blog";

    bool saveFailed;
    do
    {
        saveFailed = false;
        try
        {
            context.SaveChanges();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            saveFailed = true;

            // Update original values from the database
            var entry = ex.Entries.Single();
            entry.OriginalValues.SetValues(entry.GetDatabaseValues());
        }

    } while (saveFailed);
}

Custom resolution of optimistic concurrency exceptions

Sometimes you may want to combine the values currently in the database with the values currently in the entity. This usually requires some custom logic or user interaction. For example, you might present a form to the user containing the current values, the values in the database, and a default set of resolved values. The user would then edit the resolved values as necessary and it would be these resolved values that get saved to the database. This can be done using the DbPropertyValues objects returned from CurrentValues and GetDatabaseValues on the entity’s entry. For example:

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);
    blog.Name = "The New ADO.NET Blog";

    bool saveFailed;
    do
    {
        saveFailed = false;
        try
        {
            context.SaveChanges();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            saveFailed = true;

            // Get the current entity values and the values in the database
            var entry = ex.Entries.Single();
            var currentValues = entry.CurrentValues;
            var databaseValues = entry.GetDatabaseValues();

            // Choose an initial set of resolved values. In this case we
            // make the default be the values currently in the database.
            var resolvedValues = databaseValues.Clone();

            // Have the user choose what the resolved values should be
            HaveUserResolveConcurrency(currentValues, databaseValues, resolvedValues);

            // Update the original values with the database values and
            // the current values with whatever the user choose.
            entry.OriginalValues.SetValues(databaseValues);
            entry.CurrentValues.SetValues(resolvedValues);
        }
    } while (saveFailed);
}

public void HaveUserResolveConcurrency(DbPropertyValues currentValues,
                                       DbPropertyValues databaseValues,
                                       DbPropertyValues resolvedValues)
{
    // Show the current, database, and resolved values to the user and have
    // them edit the resolved values to get the correct resolution.
}

Custom resolution of optimistic concurrency exceptions using objects

The code above uses DbPropertyValues instances for passing around current, database, and resolved values. Sometimes it may be easier to use instances of your entity type for this. This can be done using the ToObject and SetValues methods of DbPropertyValues. For example:

C#
using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);
    blog.Name = "The New ADO.NET Blog";

    bool saveFailed;
    do
    {
        saveFailed = false;
        try
        {
            context.SaveChanges();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            saveFailed = true;

            // Get the current entity values and the values in the database
            // as instances of the entity type
            var entry = ex.Entries.Single();
            var databaseValues = entry.GetDatabaseValues();
            var databaseValuesAsBlog = (Blog)databaseValues.ToObject();

            // Choose an initial set of resolved values. In this case we
            // make the default be the values currently in the database.
            var resolvedValuesAsBlog = (Blog)databaseValues.ToObject();

            // Have the user choose what the resolved values should be
            HaveUserResolveConcurrency((Blog)entry.Entity,
                                       databaseValuesAsBlog,
                                       resolvedValuesAsBlog);

            // Update the original values with the database values and
            // the current values with whatever the user choose.
            entry.OriginalValues.SetValues(databaseValues);
            entry.CurrentValues.SetValues(resolvedValuesAsBlog);
        }

    } while (saveFailed);
}

public void HaveUserResolveConcurrency(Blog entity,
                                       Blog databaseValues,
                                       Blog resolvedValues)
{
    // Show the current, database, and resolved values to the user and have
    // them update the resolved values to get the correct resolution.
}

Working with Data Providers

The topics in this section describe the services and providers that transform queries against a conceptual model into native queries against a data source that is supported by the Entity Framework.

See also

Connection Strings in the ADO.NET Entity Framework

A connection string contains initialization information that is passed as a parameter from a data provider to a data source. The syntax depends on the data provider, and the connection string is parsed during the attempt to open a connection. Connection strings used by the Entity Framework contain information used to connect to the underlying ADO.NET data provider that supports the Entity Framework. They also contain information about the required model and mapping files.

The connection string is used by the EntityClient provider when accessing model and mapping metadata and connecting to the data source. The connection string can be accessed or set through the ConnectionString property of EntityConnection. The EntityConnectionStringBuilder class can be used to programmatically construct or access parameters in the connection string. For more information, see How to: Build an EntityConnection Connection String.

The Entity Data Model tools generate a connection string that is stored in the application's configuration file. ObjectContext retrieves this connection information automatically when creating object queries. The EntityConnection used by an ObjectContext instance can be accessed from the Connection property. For more information, see Managing Connections and Transactions.

Connection String Syntax

To learn about the general syntax for connection strings, see Connection string syntax | Connection Strings in ADO.NET.

Connection String Parameters

The following table lists the valid names for keyword values in the ConnectionString.

Keyword Description
Provider Required if the Name keyword is not specified. The provider name, which is used to retrieve the DbProviderFactory object for the underlying provider. This value is constant.

When the Name keyword is not included in an entity connection string, a non-empty value for the Provider keyword is required. This keyword is mutually exclusive with the Name keyword.
Provider Connection String Optional. Specifies the provider-specific connection string that is passed to the underlying data source. This connection string contains valid keyword/value pairs for the data provider. An invalid Provider Connection String will cause a run-time error when it is evaluated by the data source.

This keyword is mutually exclusive with the Name keyword.

Make sure to escape the value according to the general syntax of ADO.NET connection strings. Consider for example the following connection string: Server=serverName; User ID = userID. It must be escaped because it contains a semicolon. Since it does not contain double quotation marks, they may be used for escaping:

Provider Connection String ="Server=serverName; User ID = userID";
Metadata Required if the Name keyword is not specified. A pipe-delimited list of directories, files, and resource locations in which to look for metadata and mapping information. The following is an example:

Metadata=

c:\model &#124; c:\model\sql\mapping.msl;

Blank spaces on each side of the pipe separator are ignored.

This keyword is mutually exclusive with the Name keyword.
Name The application can optionally specify the connection name in an application configuration file that provides the required keyword/value connection string values. In this case, you cannot supply them directly in the connection string. The Name keyword is not allowed in a configuration file.

When the Name keyword is not included in the connection string, a non-empty values for Provider keyword is required.

This keyword is mutually exclusive with all the other connection string keywords.

The following is an example of a connection string for the AdventureWorks Sales Model stored in the application configuration file:

Model and Mapping File Locations

The Metadata parameter contains a list of locations for the EntityClient provider to search for model and mapping files. Model and mapping files are often deployed in the same directory as the application executable file. These files can also be deployed in a specific location or included as an embedded resource in the application.

Embedded resources are specified as follows:

Metadata=res://<assemblyFullName>/<resourceName>.

The following options are available for defining the location of an embedded resource:

Option Description
assemblyFullName The full name of an assembly with the embedded resource. The name includes the simple name, version name, supported culture, and public key, as follows:

ResourceLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

Resources can be embedded in any assembly that is accessible by the application.

If you specify a wildcard (*) for assemblyFullName, the Entity Framework runtime will search for resources in the following locations, in this order:

1. The calling assembly.
2. The referenced assemblies.
3. The assemblies in the bin directory of an application.

If the files are not in one of these locations, an exception will be thrown. Note: When you use wildcard (*), the Entity Framework has to look through all the assemblies for resources with the correct name. To improve performance, specify the assembly name instead of the wildcard.
resourceName The name of the included resource, such as AdventureWorksModel.csdl. The metadata services will only look for files or resources with one of the following extensions: .csdl, .ssdl, or .msl. If resourceName is not specified, all metadata resources will be loaded. The resources should have unique names within an assembly. If multiple files with the same name are defined in different directories in the assembly, the resourceName must include the folder structure before the name of the resource, for example FolderName.FileName.csdl.

resourceName is not required when you specify a wildcard (*) for assemblyFullName.

Note

To improve performance, embed resources in the calling assembly, except in non-Web scenarios where there is no reference to underlying mapping and metadata files in the calling assembly.

The following example loads all the model and mapping files in the calling assembly, referenced assemblies, and other assemblies in the bin directory of an application.

Metadata=res://*/

The following example loads the model.csdl file from the AdventureWorks assembly, and loads the model.ssdl and model.msl files from the default directory of the running application.

Metadata=res://AdventureWorks, 1.0.0.0, neutral, a14f3033def15840/model.csdl|model.ssdl|model.msl

The following example loads the three specified resources from the specific assembly.

Metadata=res://AdventureWorks, 1.0.0.0, neutral, a14f3033def15840/model.csdl|
res://AdventureWorks, 1.0.0.0, neutral, a14f3033def15840/model.ssdl|
res://AdventureWorks, 1.0.0.0, neutral, a14f3033def15840/model.msl

The following example loads all the embedded resources with the extensions .csdl, .msl, and .ssdl from the assembly.

Metadata=res://AdventureWorks, 1.0.0.0, neutral, a14f3033def15840/

The following example loads all the resources in the relative file path plus "datadir\metadata\" from the loaded assembly location.

Metadata=datadir\metadata\

The following example loads all the resources in the relative file path from the loaded assembly location.

Metadata=.\

Support for the |DataDirectory| Substitution String and the Web Application Root Operator (~)

DataDirectory and the ~ operator are used in the ConnectionString as part of the Metadata and Provider Connection String keywords. The EntityConnection forwards the DataDirectory and the ~ operator to MetadataWorkspace and the store provider, respectively.

Term Description
&#124;DataDirectory&#124; Resolves to a relative path to a mapping and metadata files. This is the value that is set through the AppDomain.SetData("DataDirectory", objValue) method. The DataDirectory substitution string must be surrounded by the pipe characters and there cannot be any white space between its name and the pipe characters. The DataDirectory name is not case-sensitive.

If a physical directory named "DataDirectory" has to be passed as a member of the list of metadata paths, add white space to either or both sides of the name. For example: Metadata="DataDirectory1 &#124; DataDirectory &#124; DataDirectory2". An ASP.NET application resolves |DataDirectory| to the "<application root>/app_data" folder.
~ Resolves to the Web application root. The ~ character at a leading position is always interpreted as the Web application root operator (~), although it might represent a valid local subdirectory. To refer to such a local subdirectory, the user should explicitly pass ./~.

DataDirectory and the ~ operator should be specified only at the beginning of a path, they are not resolved at any other position. The Entity Framework will try to resolve ~/data, but it will treat /data/~ as a physical path.

A path that starts with the DataDirectory or the ~ operator cannot resolve to a physical path outside the branch of the DataDirectory and the ~ operator. For example, the following paths will resolve: ~ , ~/data , ~/bin/Model/SqlServer. The following paths will fail to resolve: ~/.., ~/../other.

DataDirectory and the ~ operator can be extended to include sub-directories, as follows: |DataDirectory|\Model, ~/bin/Model

The resolution of the DataDirectory substitution string and the ~ operator is non-recursive. For example, when DataDirectory includes the ~ character, an exception will occur. This prevents an infinite recursion.

See also

Entity Framework Data Providers

This section provides information on data providers that support the Entity Framework.

In This Section

EntityClient Provider for the Entity Framework
Describes the EntityClient data provider. This provider transforms queries against a data model into a canonical command tree. The command tree can then be consumed by a .NET Framework data provider for the Entity Framework.

SqlClient for the Entity Framework
Describes the .NET Framework data provider that supports the Entity Framework for use with a SQL Server database.

Related Sections

Entity Framework (SQL Server Compact)
Describes provider limitations and how to use the Entity Framework with a SQL Server Compact database.

Third-Party Providers for the Entity Framework
List of the third-party data providers currently available for the Entity Framework.

See also

EntityClient Provider for the Entity Framework

The EntityClient provider is a data provider used by Entity Framework applications to access data described in a conceptual model. For information about conceptual models, see Modeling and Mapping. EntityClient uses other .NET Framework data providers to access the data source. For example, EntityClient uses the .NET Framework Data Provider for SQL Server (SqlClient) when accessing a SQL Server database. For information about the SqlClient provider, see SqlClient for the Entity Framework. The EntityClient provider is implemented in the System.Data.EntityClient namespace.

Managing Connections

The Entity Framework builds on top of storage-specific ADO.NET data providers by providing an EntityConnection to an underlying data provider and relational database. To construct an EntityConnection object, you have to reference a set of metadata that contains the necessary models and mapping, and also a storage-specific data provider name and connection string. After the EntityConnection is in place, entities can be accessed through the classes generated from the conceptual model.

You can specify a connection string in app.config file.

The System.Data.EntityClient also includes the EntityConnectionStringBuilder class. This class enables developers to programmatically create syntactically correct connection strings, and parse and rebuild existing connection strings, by using properties and methods of the class. For more information, see How to: Build an EntityConnection Connection String.

Creating Queries

The Entity SQL language is a storage-independent dialect of SQL that works directly with conceptual entity schemas and supports Entity Data Model concepts such as inheritance and relationships. The EntityCommand class is used to execute an Entity SQL command against an entity model. When you construct EntityCommand objects, you can specify a stored procedure name or a query text. The Entity Framework works with storage-specific data providers to translate generic Entity SQL into storage-specific queries. For more information about writing Entity SQL queries, see Entity SQL Language.

The following example creates an EntityCommand object and assigns an Entity SQL query text to its EntityCommand.CommandText property. This Entity SQL query requests products ordered by the list price from the conceptual model. The following code has no knowledge of the storage model at all.

C#
EntityCommand cmd = conn.CreateCommand();
cmd.CommandText = @"SELECT VALUE p
 FROM AdventureWorksEntities.Product AS p
 ORDER BY p.ListPrice";

Executing Queries

When a query is executed, it is parsed and converted into a canonical command tree. All subsequent processing is performed on the command tree. The command tree is the means of communication between the System.Data.EntityClient and the underlying .NET Framework data provider, such as System.Data.SqlClient.

The EntityDataReader exposes the results of executing a EntityCommand against a conceptual model. To execute the command that returns the EntityDataReader, call ExecuteReader. The EntityDataReader implements IExtendedDataRecord to describe rich structured results.

Managing Transactions

In the Entity Framework, there are two ways to use transactions: automatic and explicit. Automatic transactions use the System.Transactions namespace, and explicit transactions use the EntityTransaction class.

To update data that is exposed through a conceptual model, see How to: Manage Transactions in the Entity Framework.

In This Section

How to: Build an EntityConnection Connection String

How to: Execute a Query that Returns PrimitiveType Results

How to: Execute a Query that Returns StructuralType Results

How to: Execute a Query that Returns RefType Results

How to: Execute a Query that Returns Complex Types

How to: Execute a Query that Returns Nested Collections

How to: Execute a Parameterized Entity SQL Query Using EntityCommand

How to: Execute a Parameterized Stored Procedure Using EntityCommand

How to: Execute a Polymorphic Query

How to: Navigate Relationships with the Navigate Operator

See also

How to: Build an EntityConnection Connection String

This topic provides an example of how to build an EntityConnection.

To run the code in this example

  1. Add the AdventureWorks Sales Model to your project and configure your project to use the Entity Framework. For more information, see How to: Use the Entity Data Model Wizard.

  2. In the code page for your application, add the following using statements (Imports in Visual Basic):

    C#
  1. using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Data.Common;
    using System.Data;
    using System.IO;
    using System.Data.SqlClient;
    using System.Data.EntityClient;
    using System.Data.Metadata.Edm;
    

Example

The following example initializes the System.Data.SqlClient.SqlConnectionStringBuilder for the underlying provider, then initializes the System.Data.EntityClient.EntityConnectionStringBuilder object and passes this object to the constructor of the EntityConnection.

C#
// Specify the provider name, server and database.
string providerName = "System.Data.SqlClient";
string serverName = ".";
string databaseName = "AdventureWorks";

// Initialize the connection string builder for the
// underlying provider.
SqlConnectionStringBuilder sqlBuilder =
    new SqlConnectionStringBuilder();

// Set the properties for the data source.
sqlBuilder.DataSource = serverName;
sqlBuilder.InitialCatalog = databaseName;
sqlBuilder.IntegratedSecurity = true;

// Build the SqlConnection connection string.
string providerString = sqlBuilder.ToString();

// Initialize the EntityConnectionStringBuilder.
EntityConnectionStringBuilder entityBuilder =
    new EntityConnectionStringBuilder();

//Set the provider name.
entityBuilder.Provider = providerName;

// Set the provider-specific connection string.
entityBuilder.ProviderConnectionString = providerString;

// Set the Metadata location.
entityBuilder.Metadata = @"res://*/AdventureWorksModel.csdl|
                            res://*/AdventureWorksModel.ssdl|
                            res://*/AdventureWorksModel.msl";
Console.WriteLine(entityBuilder.ToString());

using (EntityConnection conn =
    new EntityConnection(entityBuilder.ToString()))
{
    conn.Open();
    Console.WriteLine("Just testing the connection.");
    conn.Close();
}

See also

How to: Execute a Query that Returns PrimitiveType Results

This topic shows how to execute a command against a conceptual model by using an EntityCommand, and how to retrieve the PrimitiveType results by using an EntityDataReader.

To run the code in this example

  1. Add the AdventureWorks Sales Model to your project and configure your project to use the Entity Framework. For more information, see How to: Use the Entity Data Model Wizard.

  2. In the code page for your application, add the following using statements (Imports in Visual Basic):

    C#
  1. using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Data.Common;
    using System.Data;
    using System.IO;
    using System.Data.SqlClient;
    using System.Data.EntityClient;
    using System.Data.Metadata.Edm;
    

Example

This example executes a query that returns a PrimitiveType result. If you pass the following query as an argument to the ExecutePrimitiveTypeQuery function, the function displays the average list price of all Products:

C#
SELECT VALUE AVG(p.ListPrice) FROM AdventureWorksEntities.Products as p 

If you pass a parameterized query, like the following, EntityParameter objects to the Parameters property on the EntityCommand object.

C#
CASE WHEN AVG({@score1,@score2,@score3}) < @total THEN TRUE ELSE FALSE END
C#
static void ExecutePrimitiveTypeQuery(string esqlQuery)
{
    if (esqlQuery.Length == 0)
    {
        Console.WriteLine("The query string is empty.");
        return;
    }

    using (EntityConnection conn =
        new EntityConnection("name=AdventureWorksEntities"))
    {
        conn.Open();

        // Create an EntityCommand.
        using (EntityCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = esqlQuery;
            // Execute the command.
            using (EntityDataReader rdr =
                cmd.ExecuteReader(CommandBehavior.SequentialAccess))
            {
                // Start reading results.
                while (rdr.Read())
                {
                    IExtendedDataRecord record = rdr as IExtendedDataRecord;
                    // For PrimitiveType 
                    // the record contains exactly one field.
                    int fieldIndex = 0;
                    Console.WriteLine("Value: " + record.GetValue(fieldIndex));
                }
            }
        }
        conn.Close();
    }
}

See also

How to: Execute a Query that Returns StructuralType Results

This topic shows how to execute a command against a conceptual model by using an EntityCommand object, and how to retrieve the StructuralType results by using an EntityDataReader. The EntityType, RowType and ComplexType classes derive from the StructuralType class.

To run the code in this example

  1. Add the AdventureWorks Sales Model to your project and configure your project to use the Entity Framework. For more information, see How to: Use the Entity Data Model Wizard.

  2. In the code page for your application, add the following using statements (Imports in Visual Basic):

    C#
  1. using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Data.Common;
    using System.Data;
    using System.IO;
    using System.Data.SqlClient;
    using System.Data.EntityClient;
    using System.Data.Metadata.Edm;
    

Example

This example executes a query that returns EntityType results. If you pass the following query as an argument to the ExecuteStructuralTypeQuery function, the function displays details about the Products:

C#
SELECT VALUE Product FROM AdventureWorksEntities.Products AS Product

If you pass a parameterized query, like the following, add the EntityParameter objects to the Parameters property on the EntityCommand object.

C#
SELECT VALUE product FROM AdventureWorksEntities.Products 
    AS product where product.ListPrice >= @price
C#
static void ExecuteStructuralTypeQuery(string esqlQuery)
{
    if (esqlQuery.Length == 0)
    {
        Console.WriteLine("The query string is empty.");
        return;
    }

    using (EntityConnection conn =
        new EntityConnection("name=AdventureWorksEntities"))
    {
        conn.Open();

        // Create an EntityCommand.
        using (EntityCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = esqlQuery;
            // Execute the command.
            using (EntityDataReader rdr =
                cmd.ExecuteReader(CommandBehavior.SequentialAccess))
            {
                // Start reading results.
                while (rdr.Read())
                {
                    StructuralTypeVisitRecord(rdr as IExtendedDataRecord);
                }
            }
        }
        conn.Close();
    }
}

static void StructuralTypeVisitRecord(IExtendedDataRecord record)
{
    int fieldCount = record.DataRecordInfo.FieldMetadata.Count;
    for (int fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++)
    {
        Console.Write(record.GetName(fieldIndex) + ": ");

        // If the field is flagged as DbNull, the shape of the value is undetermined.
        // An attempt to get such a value may trigger an exception.
        if (record.IsDBNull(fieldIndex) == false)
        {
            BuiltInTypeKind fieldTypeKind = record.DataRecordInfo.FieldMetadata[fieldIndex].
                FieldType.TypeUsage.EdmType.BuiltInTypeKind;
            // The EntityType, ComplexType and RowType are structural types
            // that have members. 
            // Read only the PrimitiveType members of this structural type.
            if (fieldTypeKind == BuiltInTypeKind.PrimitiveType)
            {
                // Primitive types are surfaced as plain objects.
                Console.WriteLine(record.GetValue(fieldIndex).ToString());
            }
        }
    }
}

See also

How to: Execute a Query that Returns RefType Results

This topic shows how to execute a command against a conceptual model by using an EntityCommand object, and how to retrieve the RefType results by using an EntityDataReader.

To run the code in this example

  1. Add the AdventureWorks Sales Model to your project and configure your project to use the Entity Framework. For more information, see How to: Use the Entity Data Model Wizard.

  2. In the code page for your application, add the following using statements (Imports in Visual Basic):

    C#
    using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Data.Common;
    using System.Data;
    using System.IO;
    using System.Data.SqlClient;
    using System.Data.EntityClient;
    using System.Data.Metadata.Edm;
    

Example

This example executes a query that returns RefType results. If you pass the following query as an argument to the ExecuteRefTypeQuery function, the function returns a reference to the entity:

C#
SELECT REF(p) FROM AdventureWorksEntities.Products as p

If you pass a parameterized query, like the following, add the EntityParameter objects to the Parameters property on the EntityCommand object.

C#
SELECT REF(p) FROM AdventureWorksEntities.Products as p WHERE p.ProductID == @productID
C#
static public void ExecuteRefTypeQuery(string esqlQuery)
{
    if (esqlQuery.Length == 0)
    {
        Console.WriteLine("The query string is empty.");
        return;
    }

    using (EntityConnection conn =
        new EntityConnection("name=AdventureWorksEntities"))
    {
        conn.Open();

        // Create an EntityCommand.
        using (EntityCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = esqlQuery;
            // Execute the command.
            using (EntityDataReader rdr =
                cmd.ExecuteReader(CommandBehavior.SequentialAccess))
            {
                // Start reading results.
                while (rdr.Read())
                {
                    RefTypeVisitRecord(rdr as IExtendedDataRecord);
                }
            }
        }
        conn.Close();
    }
}

static void RefTypeVisitRecord(IExtendedDataRecord record)
{
    // For RefType the record contains exactly one field.
    int fieldIndex = 0;

    // If the field is flagged as DbNull, the shape of the value is undetermined.
    // An attempt to get such a value may trigger an exception.
    if (record.IsDBNull(fieldIndex) == false)
    {
        BuiltInTypeKind fieldTypeKind = record.DataRecordInfo.FieldMetadata[fieldIndex].
            FieldType.TypeUsage.EdmType.BuiltInTypeKind;
        //read only fields that contain PrimitiveType
        if (fieldTypeKind == BuiltInTypeKind.RefType)
        {
            // Ref types are surfaced as EntityKey instances. 
            // The containing record sees them as atomic.
            EntityKey key = record.GetValue(fieldIndex) as EntityKey;
            // Get the EntitySet name.
            Console.WriteLine("EntitySetName " + key.EntitySetName);
            // Get the Name and the Value information of the EntityKey.
            foreach (EntityKeyMember keyMember in key.EntityKeyValues)
            {
                Console.WriteLine("   Key Name: " + keyMember.Key);
                Console.WriteLine("   Key Value: " + keyMember.Value);
            }
        }
    }
}

See also

How to: Execute a Query that Returns Complex Types

This topic shows how to execute an Entity SQL query that returns entity type objects that contain a property of a complex type.

To run the code in this example

  1. Add the AdventureWorks Sales Model to your project and configure your project to use the Entity Framework. For more information, see How to: Use the Entity Data Model Wizard.

  2. In the code page for your application, add the following using statements (Imports in Visual Basic):

    C#
    using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Data.Common;
    using System.Data;
    using System.IO;
    using System.Data.SqlClient;
    using System.Data.EntityClient;
    using System.Data.Metadata.Edm;
    
  3. Double click the .edmx file to display the model in the Model Browser window of the Entity Designer. On the Entity Designer surface, select the Email and Phone properties of the Contact entity type, then right-click and select Refactor into New Complex Type.

  4. A new complex type with the selected Email and Phone properties is added to the Model Browser. The complex type is given a default name: rename the type to EmailPhone in the Properties window. Also, a new ComplexProperty property is added to the Contact entity type. Rename the property to EmailPhoneComplexType.

    For information about creating and modifying complex types by using the Entity Data Model Wizard, see How to: Refactor Existing Properties into a Complex Type Property and How to: Create and Modify Complex Types.

Example

The following example executes a query that returns a collection of Contact objects and displays two properties of the Contact objects: ContactID and the values of the EmailPhoneComplexType complex type.

C#
using (EntityConnection conn =
    new EntityConnection("name=AdventureWorksEntities"))
{
    conn.Open();

    string esqlQuery = @"SELECT VALUE contacts FROM
            AdventureWorksEntities.Contacts AS contacts 
            WHERE contacts.ContactID == @id";

    // Create an EntityCommand.
    using (EntityCommand cmd = conn.CreateCommand())
    {
        cmd.CommandText = esqlQuery;
        EntityParameter param = new EntityParameter();
        param.ParameterName = "id";
        param.Value = 3;
        cmd.Parameters.Add(param);

        // Execute the command.
        using (EntityDataReader rdr =
            cmd.ExecuteReader(CommandBehavior.SequentialAccess))
        {
            // The result returned by this query contains 
            // Address complex Types.
            while (rdr.Read())
            {
                // Display CustomerID
                Console.WriteLine("Contact ID: {0}",
                    rdr["ContactID"]);
                // Display Address information.
                DbDataRecord nestedRecord =
                    rdr["EmailPhoneComplexProperty"] as DbDataRecord;
                Console.WriteLine("Email and Phone Info:");
                for (int i = 0; i < nestedRecord.FieldCount; i++)
                {
                    Console.WriteLine("  " + nestedRecord.GetName(i) +
                        ": " + nestedRecord.GetValue(i));
                }
            }
        }
    }
    conn.Close();
}

How to: Execute a Query that Returns Nested Collections

This shows how to execute a command against a conceptual model by using an EntityCommand object, and how to retrieve the nested collection results by using an EntityDataReader.

To run the code in this example

  1. Add the AdventureWorks Sales Model to your project and configure your project to use the Entity Framework. For more information, see How to: Use the Entity Data Model Wizard.

  2. In the code page for your application, add the following using statements (Imports in Visual Basic):

    C#
    using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Data.Common;
    using System.Data;
    using System.IO;
    using System.Data.SqlClient;
    using System.Data.EntityClient;
    using System.Data.Metadata.Edm;
    

Example

A nested collection is a collection that is inside another collection. The following code retrieves a collection of Contacts and the nested collections of SalesOrderHeaders that are associated with each Contact.

C#
using (EntityConnection conn =
    new EntityConnection("name=AdventureWorksEntities"))
{
    conn.Open();
    // Create an EntityCommand.
    using (EntityCommand cmd = conn.CreateCommand())
    {
        // Create a nested query.
        string esqlQuery =
            @"Select c.ContactID, c.SalesOrderHeaders
        From AdventureWorksEntities.Contacts as c";

        cmd.CommandText = esqlQuery;
        // Execute the command.
        using (EntityDataReader rdr =
            cmd.ExecuteReader(CommandBehavior.SequentialAccess))
        {
            // The result returned by this query contains 
            // ContactID and a nested collection of SalesOrderHeader items.
            // associated with this Contact.
            while (rdr.Read())
            {
                // the first column contains Contact ID.
                Console.WriteLine("Contact ID: {0}", rdr["ContactID"]);

                // The second column contains a collection of SalesOrderHeader 
                // items associated with the Contact.
                DbDataReader nestedReader = rdr.GetDataReader(1);
                while (nestedReader.Read())
                {
                    Console.WriteLine("   SalesOrderID: {0} ", nestedReader["SalesOrderID"]);
                    Console.WriteLine("   OrderDate: {0} ", nestedReader["OrderDate"]);
                }
            }
        }
    }
    conn.Close();
}

See also

How to: Execute a Parameterized Entity SQL Query Using EntityCommand

This topic shows how to execute an Entity SQL query that has parameters by using an EntityCommand object.

To run the code in this example

  1. Add the AdventureWorks Sales Model to your project and configure your project to use the Entity Framework. For more information, see How to: Use the Entity Data Model Wizard.

  2. In the code page for your application, add the following using statements (Imports in Visual Basic):

    C#
  1. using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Data.Common;
    using System.Data;
    using System.IO;
    using System.Data.SqlClient;
    using System.Data.EntityClient;
    using System.Data.Metadata.Edm;
    

Example

The following example shows how to construct a query string with two parameters. It then creates an EntityCommand, adds two parameters to the EntityParameter collection of that EntityCommand, and iterates through the collection of Contact items.

C#
using (EntityConnection conn =
    new EntityConnection("name=AdventureWorksEntities"))
{
    conn.Open();
    // Create a query that takes two parameters.
    string esqlQuery =
        @"SELECT VALUE Contact FROM AdventureWorksEntities.Contacts 
                    AS Contact WHERE Contact.LastName = @ln AND
                    Contact.FirstName = @fn";

    using (EntityCommand cmd = new EntityCommand(esqlQuery, conn))
    {
        // Create two parameters and add them to 
        // the EntityCommand's Parameters collection 
        EntityParameter param1 = new EntityParameter();
        param1.ParameterName = "ln";
        param1.Value = "Adams";
        EntityParameter param2 = new EntityParameter();
        param2.ParameterName = "fn";
        param2.Value = "Frances";

        cmd.Parameters.Add(param1);
        cmd.Parameters.Add(param2);

        using (DbDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
        {
            // Iterate through the collection of Contact items.
            while (rdr.Read())
            {
                Console.WriteLine(rdr["FirstName"]);
                Console.WriteLine(rdr["LastName"]);
            }
        }
    }
    conn.Close();
}

See also

How to: Execute a Parameterized Stored Procedure Using EntityCommand

This topic shows how to execute a parameterized stored procedure by using the EntityCommand class.

To run the code in this example

  1. Add the School Model to your project and configure your project to use the Entity Framework. For more information, see How to: Use the Entity Data Model Wizard.

  2. In the code page for your application, add the following using statements (Imports in Visual Basic):

    C#
    using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Data.Common;
    using System.Data;
    using System.IO;
    using System.Data.SqlClient;
    using System.Data.EntityClient;
    using System.Data.Metadata.Edm;
    
  3. Import the GetStudentGrades stored procedure and specify CourseGrade entities as a return type. For information on how to import a stored procedure, see How to: Import a Stored Procedure.

Example

The following code executes the GetStudentGrades stored procedure where StudentId is a required parameter. The results are then read by an EntityDataReader.

C#
using (EntityConnection conn =
    new EntityConnection("name=SchoolEntities"))
{
    conn.Open();
    // Create an EntityCommand.
    using (EntityCommand cmd = conn.CreateCommand())
    {
        cmd.CommandText = "SchoolEntities.GetStudentGrades";
        cmd.CommandType = CommandType.StoredProcedure;
        EntityParameter param = new EntityParameter();
        param.Value = 2;
        param.ParameterName = "StudentID";
        cmd.Parameters.Add(param);

        // Execute the command.
        using (EntityDataReader rdr =
            cmd.ExecuteReader(CommandBehavior.SequentialAccess))
        {
            // Read the results returned by the stored procedure.
            while (rdr.Read())
            {
                Console.WriteLine("ID: {0} Grade: {1}", rdr["StudentID"], rdr["Grade"]);
            }
        }
    }
    conn.Close();
}

See also

How to: Execute a Polymorphic Query

This topic shows how to execute a polymorphic Entity SQL query using the OFTYPE operator.

To run the code in this example

  1. Add the School Model to your project and configure your project to use the Entity Framework. For more information, see How to: Use the Entity Data Model Wizard.

  2. In the code page for your application, add the following using statements (Imports in Visual Basic):

    C#
    using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Data.Common;
    using System.Data;
    using System.IO;
    using System.Data.SqlClient;
    using System.Data.EntityClient;
    using System.Data.Metadata.Edm;
    
  3. Modify the conceptual model to have a table-per-hierarchy inheritance by following the steps in Walkthrough: Mapping Inheritance - Table-per-Hierarchy.

Example

The following example uses an OFTYPE operator to get and display a collection of only OnsiteCourses from a collection of Courses.

C#
using (EntityConnection conn = new EntityConnection("name=SchoolEntities"))
{
    conn.Open();
    // Create a query that specifies to 
    // get a collection of only OnsiteCourses.

    string esqlQuery = @"SELECT VAlUE onsiteCourse FROM 
        OFTYPE(SchoolEntities.Courses, SchoolModel.OnsiteCourse) 
        AS onsiteCourse";
    using (EntityCommand cmd = new EntityCommand(esqlQuery, conn))
    {
        // Execute the command.
        using (DbDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
        {
            // Start reading.
            while (rdr.Read())
            {
                // Display OnsiteCourse's location.
                Console.WriteLine("CourseID: {0} ", rdr["CourseID"]);
                Console.WriteLine("Location: {0} ", rdr["Location"]);
            }
        }
    }
}

See also

How to: Navigate Relationships with the Navigate Operator

This topic shows how to execute a command against a conceptual model by using an EntityCommand object, and how to retrieve the RefType results by using an EntityDataReader.

To run the code in this example

  1. Add the AdventureWorks Sales Model to your project and configure your project to use the Entity Framework. For more information, see How to: Use the Entity Data Model Wizard.

  2. In the code page for your application, add the following using statements (Imports in Visual Basic):

    C#
    using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Data.Common;
    using System.Data;
    using System.IO;
    using System.Data.SqlClient;
    using System.Data.EntityClient;
    using System.Data.Metadata.Edm;
    

Example

The following example shows how to navigate relationships in Entity SQL by using the NAVIGATE operator. The Navigate operator takes the following parameters: an instance of an entity, the relationship type, the end of the relationship, and the beginning of the relationship. Optionally, you can pass only an instance of an entity and the relationship type to the Navigate operator.

C#
using (EntityConnection conn =
    new EntityConnection("name=AdventureWorksEntities"))
{
    conn.Open();
    // Create an EntityCommand.
    using (EntityCommand cmd = conn.CreateCommand())
    {
        // Create an Entity SQL query.
        string esqlQuery =
            @"SELECT address.AddressID, (SELECT VALUE DEREF(soh) FROM 
          NAVIGATE(address, AdventureWorksModel.FK_SalesOrderHeader_Address_BillToAddressID) 
          AS soh) FROM AdventureWorksEntities.Addresses AS address";

        
        cmd.CommandText = esqlQuery;

        // Execute the command.
        using (DbDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
        {
            // Start reading.
            while (rdr.Read())
            {
                Console.WriteLine(rdr["AddressID"]);
            }
        }
    }
    conn.Close();
}

See also

SqlClient for the Entity Framework

This section describes the .NET Framework Data Provider for SQL Server (SqlClient), which enables the Entity Framework to work over Microsoft SQL Server.

Provider Schema Attribute

Provider is an attribute of the Schema element in store schema definition language (SSDL).

To use SqlClient, assign the string "System.Data.SqlClient" to the Provider attribute of the Schema element.

ProviderManifestToken Schema Attribute

ProviderManifestToken is a required attribute of the Schema element in SSDL. This token is used to load the provider manifest for offline scenarios. For more information about ProviderManifestToken attribute, see Schema Element (SSDL).

SqlClient can be used as a data provider for different versions of SQL Server. These versions have different capabilities. For example, SQL Server 2000 does not support varchar(max) and nvarchar(max) types that were introduced with SQL Server 2005.

SqlClient produces and accepts the following provider manifest tokens for different versions of SQL Server.

SQL Server 2000 SQL Server 2005 SQL Server 2008
2000 2005 2008

Note

Starting with Visual Studio 2010, the ADO.NET Entity Data Model Tools do not support SQL Server 2000.

Provider Namespace Name

All providers must specify a namespace. This property tells the Entity Framework which prefix is used by the provider for specific constructs, such as types and functions. The namespace for SqlClient provider manifests is SqlServer. For more information about namespaces, see Namespaces.

Types

The SqlClient provider for the Entity Framework provides mapping information between conceptual model types and SQL Server types. For more information, see SqlClient for Entity FrameworkTypes.

Functions

The SqlClient provider for the Entity Framework defines the list of functions supported by the provider. For a list of the supported functions, see SqlClient for Entity Framework Functions.

In This Section

SqlClient for Entity Framework Functions

SqlClient for Entity FrameworkTypes

Known Issues in SqlClient for Entity Framework

See also

SqlClient for Entity Framework Functions

The .NET Framework Data Provider for SQL Server (SqlClient) for the Entity Framework provides a set of functions to perform mathematical and aggregation calculations, as well as functions to perform System.DateTime and string operations. These functions are in the SQLServer namespace.

For a list of functions that should work with any provider, see Canonical Functions.

For information about how canonical functions map to SQL Server functions, see Conceptual Model Canonical to SQL Server Functions Mapping.

In This Section

Conceptual Model Canonical to SQL Server Functions Mapping

Aggregate Functions

Date and Time Functions

Mathematical Functions

String Functions

System Functions

See also

Conceptual Model Canonical to SQL Server Functions Mapping

This topic describes how conceptual model canonical functions map to the corresponding SQL Server functions.

Date and Time Functions

The following table describes the date and time functions mapping:

Canonical functions SQL Server functions
AddDays(expression) DATEADD(day, number, date)
AddHours(expression) DATEADD(hour, number, date)
AddMicroseconds(expression) DATEADD(microsecond, number, date)
AddMilliseconds(expression) DATEADD(millisecond, number, date)
AddMinutes(expression) DATEADD(minute, number, date)
AddMonths(expression) DATEADD(month, number, date)
AddNanoseconds(expression) DATEADD(nanosecond, number, date)
AddSeconds(expression) DATEADD(second, number, date)
AddYears(expression) DATEADD(year, number, date)
CreateDateTime(year, month, day, hour, minute, second) For SQL Server 2000 and SQL Server 2005, a datetime formatted value is created on the server. For SQL Server 2008 and later versions, a datetime2 value is created on the server.
CreateDateTimeOffset(year, month, day, hour, minute, second, tzoffset) A datetimeoffset formatted value is created on the server.

Not supported in SQL Server 2000 or SQL Server 2005.
CreateTime(hour, minute, second) A time formatted value is created on the server.

Not supported in SQL Server 2000 or SQL Server 2005.
CurrentDateTime() SysDateTime() in SQLServer 2008.

GetDate() in SQLServer 2000 and SQLServer 2005.
CurrentDateTimeOffset() SysDateTimeOffset() in SQL Server 2008.

Not supported in SQL Server 2000 or SQL Server 2005.
CurrentUtcDateTime() SysUtcDateTime() in SQLServer 2008. GetUtcDate() in SQL Server 2000 and SQL Server 2005.
DayOfYear(expression) DatePart(dayofyear, expression)
Day(expression) DatePart(day, expression)
DiffDays(startExpression, endExpression) DATEDIFF(day, startdate, enddate)
DiffHours(startExpression, endExpression) DATEDIFF(hour, startdate, enddate)
DiffMicroseconds(startExpression, endExpression) DATEDIFF(microsecond, startdate, enddate)
DiffMilliseconds(startExpression, endExpression) DATEDIFF(millisecond, startdate, enddate)
DiffMinutes(startExpression, endExpression) DATEDIFF(minute, startdate, enddate)
DiffNanoseconds(startExpression, endExpression) DATEDIFF(nanosecond, startdate, enddate)
DiffSeconds(startExpression, endExpression) DATEDIFF(second, startdate, enddate)
DiffYears(startExpression, endExpression) DATEDIFF(year, startdate, enddate)
GetTotalOffsetMinutes(DateTimeOffset) DatePart(tzoffset, expression)
Hour(expression) DatePart(hour, expression)
Millisecond(expression) DatePart(millisecond, expression)
Minute(expression) DatePart(minute, expression)
Month(expression) DatePart(month, expression)
Second(expression) DatePart(second, expression)
Truncate(expression) For SQL Server 2000 and SQL Server 2005, a truncated datetime formatted value is created on the server. For SQL Server 2008 and later versions, a truncated datetime2 or datetimeoffset value is created on the server.
Year(expression) DatePart(YEAR, expression)

Aggregate Functions

The following table describes the aggregate functions mapping:

Canonical functions SQL Server functions
Avg(expression) AVG(expression)
BigCount(expression) BIGCOUNT(expression)
Count(expression) COUNT(expression)
Min(expression) MIN(expression)
Max(expression) MAX(expression)
StDev(expression) STDEV(expression)
StDevP(expression) STDEVP(expression)
Sum(expression) SUM(expression)
Var(expression) VAR(expression)
VarP(expression) VARP(expression)

Math functions

The following table describes the math functions mapping:

Canonical functions SQL Server functions
Abs(value) ABS(value)
Ceiling(value) CEILING(value)
Floor(value) FLOOR(value)
Power(value) POWER(value, exponent)
Round(value) ROUND(value, digits, 0)
Truncate ROUND(value , digits, 1)

String Functions

The following table describes the string functions mapping:

Canonical functions SQL Server functions
Contains(string, target) CHARINDEX(target, string)
Concat(string1, string2) string1 + string2
EndsWith(string, target) CHARINDEX(REVERSE(target), REVERSE(string)) = 1

Note The CHARINDEX function returns false if the string is stored in a fixed length string column and target is a constant. In this case, the entire string is searched, including any padding trailing spaces. A possible workaround is to trim the data in the fixed length string before passing the string to the EndsWith function, as in the following example: EndsWith(TRIM(string), target)
IndexOf(target, string2) CHARINDEX(target, string2)
Left (string1, length) LEFT(string1, length)
Length (string) LEN(string)
LTrim(string) LTRIM(string)
Right (string1, length) RIGHT (string1, length)
Trim(string) LTRIM(RTRIM(string))
Replace (string1, string2, string3) REPLACE(string1, string2, string3)
Reverse (string) REVERSE (string)
RTrim(string) RTRIM(string)
StartsWith(string, target) CHARINDEX(target, string)
Substring(string, start, length) SUBSTRING(string, start, length)
ToLower(string) LOWER(string)
ToUpper(string) UPPER(string)

Bitwise Functions

The following table describes the bitwise functions mapping:

Canonical functions SQL Server functions
BitWiseAnd (value1, value2) value1 & value2
BitWiseNot (value) ~value
BitWiseOr (value1, value2) value1 | value2
BitWiseXor (value1, value2) value1 ^ value2

Aggregate Functions (SqlClient for Entity Framework)

The .NET Framework Data Provider for SQL Server (SqlClient) provides aggregate functions. Aggregate functions perform calculations on a set of input values and return a value. These functions are in the SqlServer namespace, which is available when you use SqlClient. A provider's namespace property allows the Entity Framework to discover which prefix is used by this provider for specific constructs, such as types and functions.

The following are the SqlClient aggregate functions.

AVG(expression)

Returns the average of the values in a collection. Null values are ignored.

Arguments

An Int32, Int64, Double, and Decimal.

Return Value

The type of expression.

Example

C#
SELECT VALUE SqlServer.AVG(p.ListPrice) FROM 
AdventureWorksEntities.Products as p 
SQL
SELECT VALUE SqlServer.AVG(p.ListPrice) 
FROM AdventureWorksEntities.Products AS p 

CHECKSUM_AGG(collection)

Returns the checksum of the values in a collection. Null values are ignored.

Arguments

A Collection(Int32).

Return Value

An Int32.

Example

C#
SELECT VALUE SqlServer.Checksum_Agg(cast(product.ListPrice as Int32)) 
FROM AdventureWorksEntities.Products AS product 
WHERE product.ListPrice > cast(@price as Decimal) 
SQL
SELECT VALUE SqlServer.Checksum_Agg(cast(product.ListPrice AS Int32)) 
FROM AdventureWorksEntities.Products AS product 
WHERE product.ListPrice > cast(@price AS Decimal) 

COUNT(expression)

Returns the number of items in a collection as an Int32.

Arguments

A Collection<T>, where T is one of the following types:

Boolean Double DateTime DateTimeOffset
Time String Binary Guid (not returned in SQL Server 2000)

Return Value

An Int32.

Example

C#
ANYELEMENT(SELECT VALUE SqlServer.COUNT(product.ProductID) 
FROM AdventureWorksEntities.Products AS product 
WHERE SqlServer.CEILING(product.ListPrice) == 
SqlServer.FLOOR(product.ListPrice)) 

[!code-sql[DP EntityServices Concepts#SQLSERVER_COUNT](~/samples/snippets/tsql/VS_Snippets_Data/dp entityservices concepts/tsql/entitysql.sql#sqlserver_count)

COUNT_BIG(expression)

Returns the number of items in a collection as a bigint.

Arguments

A Collection(T), where T is one of the following types:

Boolean Double DateTime DateTimeOffset
Time String Binary Guid (not returned in SQL Server 2000)

Return Value

An Int64.

Example

C#
ANYELEMENT(SELECT VALUE SqlServer.COUNT_BIG(product.ProductID) 
FROM AdventureWorksEntities.Products AS product 
WHERE SqlServer.CEILING(product.ListPrice) == 
SqlServer.FLOOR(product.ListPrice)) 
SQL
ANYELEMENT(SELECT VALUE SqlServer.COUNT_BIG(product.ProductID) 
FROM AdventureWorksEntities.Products AS product 
WHERE SqlServer.CEILING(product.ListPrice) == 
SqlServer.FLOOR(product.ListPrice)) 

MAX(expression)

Returns the maximum value the collection.

Arguments

A Collection(T), where T is one of the following types:

Boolean Double DateTime DateTimeOffset
Time String Binary

Return Value

The type of expression.

Example

C#
SELECT VALUE SqlServer.MAX(p.ListPrice) 
FROM AdventureWorksEntities.Products as p
SQL
SELECT VALUE SqlServer.MAX(p.ListPrice) 
FROM AdventureWorksEntities.Products AS p

MIN(expression)

Returns the minimum value in a collection.

Arguments

A Collection(T), where T is one of the following types:

Boolean Double DateTime DateTimeOffset
Time String Binary

Return Value

The type of expression.

Example

C#
SELECT VALUE SqlServer.MIN(p.ListPrice) 
FROM AdventureWorksEntities.Products as p
SQL
SELECT VALUE SqlServer.MIN(p.ListPrice) 
FROM AdventureWorksEntities.Products AS p

STDEV(expression)

Returns the statistical standard deviation of all values in the specified expression.

Arguments

A Collection(Double).

Return Value

A Double.

Example

C#
SELECT VALUE SqlServer.STDEV(product.ListPrice) 
FROM AdventureWorksEntities.Products AS product 
WHERE product.ListPrice > cast(@price as Decimal) 
SQL
SELECT VALUE SqlServer.STDEV(product.ListPrice) 
FROM AdventureWorksEntities.Products AS product 
WHERE product.ListPrice > cast(@price AS Decimal) 

STDEVP(expression)

Returns the statistical standard deviation for the population for all values in the specified expression.

Arguments

A Collection(Double).

Return Value

A Double.

Example

C#
SELECT VALUE SqlServer.STDEVP(product.ListPrice) 
FROM AdventureWorksEntities.Products AS product 
WHERE product.ListPrice > cast(@price as Decimal) 
SQL
SELECT VALUE SqlServer.STDEVP(product.ListPrice) 
FROM AdventureWorksEntities.Products AS product 
WHERE product.ListPrice > cast(@price AS Decimal) 

SUM(expression)

Returns the sum of all the values in the collection.

Arguments

A Collection(T) where T is one of the following types: Int32, Int64, Double, Decimal.

Return Value

The type of expression.

Example

C#
SELECT VALUE SqlServer.SUM(p.ListPrice) 
FROM AdventureWorksEntities.Products as p
SQL
SELECT VALUE SqlServer.SUM(p.ListPrice) 
FROM AdventureWorksEntities.Products AS p

VAR(expression)

Returns the statistical variance of all values in the specified expression.

Arguments

A Collection(Double).

Return Value

A Double.

Example

C#
SELECT VALUE SqlServer.VAR(product.ListPrice) 
FROM AdventureWorksEntities.Products AS product 
WHERE product.ListPrice > cast(@price as Decimal) 
SQL
SELECT VALUE SqlServer.VAR(product.ListPrice) 
FROM AdventureWorksEntities.Products AS product 
WHERE product.ListPrice > cast(@price AS Decimal) 

VARP(expression)

Returns the statistical variance for the population for all values in the specified expression.

Arguments

A Collection(Double).

Return Value

A Double.

Example

C#
SELECT VALUE SqlServer.VARP(product.ListPrice) 
FROM AdventureWorksEntities.Products AS product 
WHERE product.ListPrice > cast(@price as Decimal) 
SQL
SELECT VALUE SqlServer.VARP(product.ListPrice) 
FROM AdventureWorksEntities.Products AS product 
WHERE product.ListPrice > cast(@price AS Decimal) 

See also

For more information about the aggregate functions that SqlClient supports, see the documentation for the SQL Server version that you specified in the SqlClient provider manifest:

Date and Time Functions

The .NET Framework Data Provider for SQL Server (SqlClient) provides date and time functions that perform operations on a System.DateTime input value and return a string, numeric, or System.DateTime value result. These functions are in the SqlServer namespace, which is available when you use SqlClient. A provider's namespace property allows the Entity Framework to discover which prefix is used by this provider for specific constructs, such as types and functions. The following table shows the SqlClient date and time functions.

Function Description
DATEADD(datepart, number, date) Returns a new DateTime value that is based on adding an interval to the specified date.

Arguments

datepart: A String that represents the part of the date on which to return a new value.

number: The Int32, Int64, Decimal, or Double value used to increment datepart.

date: An expression that returns a DateTime, or DateTimeOffset, or Time with precision = [0-7], or a character string in a date format.

Return Value

A new DateTime, or DateTimeOffset, or Time value with precision = [0-7].

Example

SqlServer.DATEADD('day', 22, cast('6/9/2006' as DateTime))
DATEDIFF(datepart,startdate,enddate) Returns the number of date and time boundaries crossed between two specified dates.

Arguments

datepart: A String that represents the part of the date to calculate the difference.

startdate: A starting date for the calculation is an expression that returns a DateTime, or DateTimeOffset, or Time value with precision = [0-7], or a character string in a date format.

enddate: An ending date for the calculation is an expression that returns a DateTime, or DateTimeOffset, or Time value with precision = [0-7], or a character string in a date format.

Return Value

An Int32.

Example

SqlServer.DATEDIFF('day', cast('6/9/2006' as DateTime),

cast('6/20/2006' as DateTime))
DATENAME(datepart, date) Returns a character string representing the specified datepart of the specified date.

Arguments

datepart: A String that represents the part of the date on which to return a new value.

date: An expression that returns a DateTime, or DateTimeOffset, or Time value with precision = [0-7], or a character string in a date format.

Return Value

The character string representing the specified datepart of the specified date.

Example

SqlServer.DATENAME('year', cast('6/9/2006' as DateTime))
DATEPART(datepart, date) Returns an integer that represents the specified datepart of the specified date.

Arguments

datepart: A String that represents the part of the date on which to return a new value.

date: An expression that returns a DateTime, or DateTimeOffset, or Time value with precision = [0-7], or a character string in a date format.

Return Value

The specified datepart of the specified date, as an Int32.

Example

SqlServer.DATEPART('year', cast('6/9/2006' as DateTime))
DAY(date) Returns the day of the specified date as an integer.

Arguments

date:An expression of type DateTime or DateTimeOffset with precision = 0-7.

Return Value

The day of the specified date as an Int32.

Example

SqlServer.DAY(cast('6/9/2006' as DateTime))
GETDATE() Produces the current date and time in SQL Server internal format for datetime values.

Return Value

The current system date and time as a DateTime with a precision of 3.

Example

SqlServer.GETDATE()
GETUTCDATE() Produces the datetime value in UTC (Coordinated Universal Time or Greenwich Mean Time) format.

Return Value

The DateTime value with a precision of 3 in UTC format.

Example

SqlServer.GETUTCDATE()
MONTH(date) Returns the month of the specified date as an integer.

Arguments

date:An expression of type DateTime or DateTimeOffset with precision = 0-7.

Return Value

The month of the specified date as an Int32.

Example

SqlServer.MONTH(cast('6/9/2006' as DateTime))
YEAR(date) Returns the year of the specified date as an integer.

Arguments

date:An expression of type DateTime or DateTimeOffset with precision = 0-7.

Return Value

The year of the specified date as an Int32.

Example

SqlServer.YEAR(cast('6/9/2006' as DateTime))
SYSDATETIME() Returns a DateTime value with a precision of 7.

Return Value

A DateTime value with a precision of 7.

Example

SqlServer.SYSDATETIME()
SYSUTCDATE() Produces the datetime value in UTC (Coordinated Universal Time or Greenwich Mean Time) format.

Return Value

The DateTime value with precision = 7 in UTC format.

Example

SqlServer.SYSUTCDATE()
SYSDATETIMEOFFSET() Returns a DateTimeOffset with a precision of 7.

Return Value

A DateTimeOffset value with precision of 7 in UTC format.

Example

SqlServer.SYSDATETIMEOFFSET()

For more information about the date and time functions that SqlClient supports, see the documentation for the SQL Server version that you specified in the SqlClient provider manifest:

SQL Server 2000 SQL Server 2005 SQL Server 2008
Date and Time Functions (Transact-SQL) Date and Time Functions (Transact-SQL) Date and Time Functions (Transact-SQL)

See also

Mathematical Functions

The .NET Framework Data Provider for SQL Server (SqlClient) provides math functions that perform calculations on input values that are provided as arguments, and return a numeric value result. These functions are in the SqlServer namespace, which is available when you use SqlClient. A provider's namespace property allows the Entity Framework to discover which prefix is used by this provider for specific constructs, such as types and functions. The following table describes the SqlClient math functions.

ABS(expression)

Performs the absolute value function.

Arguments

expression: An Int32, Int64, Double, or Decimal.

Return Value

The absolute value of the specified expression.

Example

SqlServer.ABS(-2)

ACOS(expression)

Returns the arccosine value of the specified expression.

Arguments

expression: A Double.

Return Value

A Double.

Example

SqlServer.ACOS(.9)

ASIN(expression)

Returns the arcsine value of the specified expression.

Arguments

expression: A Double.

Return Value

A Double.

Example

SqlServer.ASIN(.9)

ATAN(expression)

Returns the arctangent value of the specified numeric expression.

Arguments

expression: A Double.

Return Value

A Double.

Example

SqlServer.ATAN(9)

ATN2(expression, expression)

Returns the angle, in radians, whose tangent is between the two specified numeric expressions.

Arguments

expression: A Double.

Return Value

A Double.

Example

SqlServer.ATN2(9, 8)

CEILING(expression)

Converts the specified expression to the smallest integer that is greater than or equal to it.

Arguments

expression: An Int32, Int64, Double, or Decimal.

Return Value

An Int32, Int64, Double, or Decimal.

Example

C#
SELECT VALUE product FROM AdventureWorksEntities.Products 
AS product WHERE product.ListPrice == 
SqlServer.CEILING(product.ListPrice) 
SQL
SELECT VALUE product 
FROM AdventureWorksEntities.Products AS product 
WHERE product.ListPrice == 
SqlServer.CEILING(product.ListPrice) 

COS(expression)

Calculates the trigonometric cosine of the specified angle in radians.

Arguments

expression: A Double.

Return Value

A Double.

Example

SqlServer.COS(45)

COT(expression)

Calculates the trigonometric cotangent of the specified angle in radians.

Arguments

expression: A Double.

Return Value

A Double.

Example

SqlServer.COT(60)

DEGREES(radians)

Returns the corresponding angle in degrees.

Arguments

expression: An Int32, Int64, Double, or Decimal.

Return Value

An Int32, Int64, Double, or Decimal.

Example

SqlServer.DEGREES(3.1)

EXP(expression)

Calculates the exponential value of a specified numeric expression.

Arguments

expression: A Double.

Return Value

A Double.

Example SqlServer.EXP(1)

FLOOR(expression)

Converts the specified expression to the largest integer less than or equal to it.

Arguments

expression: A Double.

Return Value

A Double.

Example

C#
SELECT VALUE product FROM AdventureWorksEntities.Products 
AS product WHERE product.ListPrice == 
SqlServer.FLOOR(product.ListPrice) 
SQL
SELECT VALUE product 
FROM AdventureWorksEntities.Products AS product 
WHERE product.ListPrice == 
SqlServer.FLOOR(product.ListPrice) 

LOG(expression)

Calculates the natural logarithm of the specified float expression.

Arguments

expression: A Double.

Return Value

A Double.

Example

SqlServer.LOG(100)

LOG10(expression)

Returns the base-10 logarithm of the specified Double expression.

Arguments

expression: A Double.

Return Value

A Double.

Example

SqlServer.LOG10(100)

PI()

Returns the constant value of pi as a Double.

Return Value

A Double.

Example

SqlServer.PI()

POWER(numeric_expression, power_expression)

Calculates the value of a specified expression to a specified power.

Arguments

numeric_expression An Int32, Int64, Double, or Decimal.
power_expression A Double that represents the power to which to raise the numeric_expression.

Return Value

The value of the specified numeric_expression to the specified power_expression.

Example

SqlServer.POWER(2,7)

RADIANS(expression)

Converts degrees to radians.

Arguments

expression: An Int32, Int64, Double, or Decimal.

Return Value

An Int32, Int64, Double, or Decimal.

Example

SqlServer.RADIANS(360.0)

RAND([seed])

Returns a random value from 0 through 1.

Arguments

The seed value as an Int32. If the seed is not specified, the SQL Server Database Engine assigns a seed value at random. For a specified seed value, the result returned is always the same.

Return Value

A random Double value from 0 through 1.

Example

SqlServer.RAND()

ROUND(numeric_expression, length[,function])

Returns a numeric expression, rounded to the specified length or precision.

Arguments

numeric_expression An Int32, Int64, Double, or Decimal.
length An Int32 that represents the precision to which numeric_expression is to be rounded. When length is a positive number, numeric_expression is rounded to the number of decimal positions specified by length. When length is a negative number, numeric_expression is rounded on the left side of the decimal point, as specified by length.
function Optional. An Int32 that represents the type of operation to perform. When function is omitted or has a value of 0 (default), numeric_expression is rounded. When a value other than 0 is specified, numeric_expression is truncated.

Return Value

The value of the specified numeric_expression to the specified power_expression.

Example

SqlServer.ROUND(748.58, -3)

SIGN(expression)

Returns the positive (+1), zero (0), or negative (-1) sign of the specified expression.

Arguments

expression: Int32, Int64, Double, or Decimal

Return Value

An Int32, Int64, Double, or Decimal.

Example

SqlServer.SIGN(-10)

SIN(expression)

Calculates the trigonometric sine of the specified angle in radians, and returns a Double expression.

Arguments

expression: A Double.

Return Value

A Double.

Example SqlServer.SIN(20)

SQRT(expression)

Returns the square root of the specified expression.

Arguments

expression: A Double.

Return Value

A Double.

Example SqlServer.SQRT(3600)

SQUARE(expression)

Returns the square of the specified expression.

Arguments

expression: A Double.

Return Value

A Double.

Example

SqlServer.SQUARE(25)

TAN(expression)

Calculates the tangent of a specified expression.

Arguments

expression: Double

Return Value

Double

Example

SqlServer.TAN(45.0)

See also

For more information about the mathematical functions that SqlClient supports, see the documentation for the SQL Server version that you specified in the SqlClient provider manifest:

String Functions

The .NET Framework Data Provider for SQL Server (SqlClient) provides String functions that perform operations on an input String and return a String or numeric value result. These functions are in the SqlServer namespace, which is available when you use SqlClient. A provider's namespace property allows the Entity Framework to discover which prefix is used by this provider for specific constructs, such as types and functions.

The following table shows the SqlClient String functions.

Function Description
ASCII(expression) Returns the ASCII code value of the leftmost character of a string expression.

Arguments

expression: Any valid expression of an ASCII String type.

Return Value

An Int32.

Example

SqlServer.ASCII('A')
CHAR(expression) Converts an Int32 code to an ASCII String.

Arguments

expression: An Int32.

Return Value

An ASCII String.

Example

SqlServer.char(97)
CHARINDEX(expression1, expression2 [, start_location]) Returns the starting position of the specified expression in a character string.

Arguments

expression1: An expression that contains the sequence of characters to be found. The expression can be of a String (ASCII or Unicode) type or of a Binary type.

expression2: An expression, typically a column, to be searched for the specified sequence. The expression can be of a String (ASCII or Unicode) type or of a Binary type.

start_location:(Optional) An Int64 (not returned in SQL Server 2000) or Int32 that represents the character position to start searching for expression1 in expression2. If start_location is not specified, is a negative number, or is zero, the search starts at the beginning of expression2.

Return Value

An Int32.

Example

SqlServer.CHARINDEX('h', 'habcdefgh', 2)
DIFFERENCE(expression, expression) Compares the SOUNDEX values of two strings and evaluates the similarity between them.

Arguments

An ASCII or Unicode String type. expression can be a constant, a variable, or a column.

Return Value

Returns an Int32 that represents the difference between the SOUNDEX values of two character expressions. The range is from 0 through 4. 0 indicates a weak similarity or no similarity, and 4 indicates a strong similarity or the same values.

Example

// The following example returns a DIFFERENCE value of 4,

//the least possible difference or the best match.

SqlServer.DIFFERENCE('Green','Greene');
LEFT(expression, count) Returns the left part of a character string with the specified number of characters.

Arguments

expression: A Unicode or ASCII String type. Use the CAST function to explicitly convert character_expression.

count: An Int64 (not returned in SQL Server 2000) or Int32 type that specifies how many characters of character_expression will be returned.

Return Value

A Unicode or ASCII String.

Example

SqlServer.LEFT('SQL Server', 4)
LEN(expression) Returns the number of characters in the specified String expression, excluding trailing blanks.

Arguments

expression: An expression of a String (Unicode or ASCII) type or a Binary type

Return Value

An Int32.

Example

SqlServer.LEN('abcd')
LOWER(expression) Returns a String expression after converting uppercase character data to lowercase.

Arguments

expression: Any valid expression of the String type.

Return Value

A String.

Example

SqlServer.LOWER('AbB')
LTRIM(expression) Returns a String expression after removing leading spaces.

Arguments

expression: Any valid expression of String type.

Return Value

A String.

Example

SqlServer.LTRIM(' d')
NCHAR(expression) Returns a Unicode String with the specified integer code, as defined by the Unicode standard.

Arguments

expression: An Int32.

Return Value

A Unicode String.

Example

SqlServer.NCHAR(65)
PATINDEX('%pattern%', expression) Returns the starting position of the first occurrence of a pattern in a specified String expression.

Arguments

'%pattern%': An ASCII or Unicode String type. Wildcard characters can be used; however, the % character must come before and after pattern (except in searches for first or last characters).

expression: An ASCII or Unicode String to search for the specified pattern.

Return Value

An Int32.

Example

SqlServer.PATINDEX('abc', 'ab')
QUOTENAME('char_string' [, 'quote_char']) Returns a Unicode String with the delimiters added to make the input string a valid SQL Server 2005 delimited identifier.

Arguments

char_string: A Unicode String.

quote_char: A one-character string to use as the delimiter. Can be a single quotation mark ( ' ), a left or right bracket ( [ ] ), or a double quotation mark ( " ). If quote_char is not specified, brackets are used.

Return Value

A Unicode String.

Example

SqlServer.QUOTENAME('abc[]def')
REPLACE(expression1, expression2, expression3) Replaces a character expression with another character expression.

Arguments

expression1: The string expression to be searched. expression1 can be a Unicode or ASCII String type.

expression2:The substring to be found. expression2 can be a Unicode or ASCII String type.

expression3; The replacement string. expression3 can be a Unicode or ASCII String type.

Example

SqlServer.REPLACE('aabbcc', 'bc', 'zz')
REPLICATE(char_expression, int_expression) Repeats a character expression for a specified number of times.

Arguments

char_expression: A Unicode or ASCII String type.

int_expression: Int64 (not supported in SQL Server 2000) or Int32.

Return Value

A Unicode or ASCII String type.

Example

SqlServer.REPLICATE('aa',2)
REVERSE(expression) Returns a Unicode or ASCII String with its character positions reversed from the input string.

Arguments

expression: A Unicode or ASCII String type.

Return Value

A Unicode or ASCII String type.

Example

SqlServer.REVERSE('abcd')
RIGHT(char_expression, count) Returns the right part of a character string with the specified number of characters.

Arguments

char_expression:A Unicode or ASCII String type. Use the CAST function to explicitly convert character_expression.

count: An Int64 (not returned in SQL Server 2000) or Int32 type that specifies how many characters of character_expression will be returned.

Return Value

An ASCII String type.

Example

SqlServer.RIGHT('SQL Server', 6)
RTRIM(expression) Returns a Unicode or ASCII String after removing trailing spaces.

Arguments

expression: A Unicode or ASCII String type.

Return Value

A Unicode or ASCII String type.

Example

SqlServer.RTRIM(' d e ')
SOUNDEX(expression) Returns a four-character (SOUNDEX) code to evaluate the similarity of two strings.Arguments

expression: A Unicode or ASCII String type.

Return Value

An ASCII String. A four-character (SOUNDEX) code is a string that evaluates the similarity of two strings.

Example

Select SqlServer.SOUNDEX('Smith'), SqlServer.SOUNDEX('Smythe') FROM {1}

Returns

----- ----- S530 S530
SPACE(int_expression) Returns an ASCII String of repeated spaces.

Arguments

int_expression: An Int64 (not returned in SQL Server 2000) or Int32 that indicates the number of spaces.

Return Value

An ASCII String.

Example

SqlServer.SPACE(2)
STR(float_expression [, length [, decimal]]) Returns an ASCII String converted from numeric data.

Arguments

float _expression: A expression of approximate numeric (Double) data type with a decimal point.

length: (optional) An Int32 that represents the total length. This includes decimal point, sign, digits, and spaces. The default is 10.

decimal:(optional) An Int32 that represents the number of places to the right of the decimal point. decimal must be less than or equal to 16. If decimal is more than 16, the result is truncated to sixteen places to the right of the decimal point.

Return Value

An ASCII String.

Example

SqlServer.STR(212.0)
STUFF(str_expression, start, length, str_expression_to_insert) Deletes a specified length of characters and inserts another set of characters at a specified starting point in a string expression.

Arguments

str_expression: A Unicode or ASCII String.

start: An Int64 (not returned in SQL Server 2000) or Int32 value that specifies the location to start the deletion and insertion.

length: An Int64 (not returned in SQL Server 2000) or Int32 value that specifies the number of characters to delete.

str_expression_to_insert: A Unicode or ASCII String.

Return Value

A Unicode or ASCII String.

Example

SqlServer.STUFF('abcd', 2, 2, 'zz')
SUBSTRING(str_expression, start, length) Returns part of a String expression.

Arguments

str_expression: An expression of a String (ASCII or Unicode) type or a Binary type.

start: An Int64 (not returned in SQL Server 2000) or Int32 that specifies where the substring starts. 1 refers to the first character in the string.

length: An Int64 (not returned in SQL Server 2000) or Int32 that specifies how many characters of the expression will be returned.

Return Value

A String (ASCII or Unicode) type or a Binary type.

Example

SqlServer.SUBSTRING('abcd', 2, 2)
UNICODE(expression) Returns the integer value, as defined by the Unicode standard, for the first character of the input expression.

Arguments

expression: A Unicode String.

Return Value

An Int32.

Example

SqlServer.UNICODE('a')
UPPER(expression) Returns a String expression after converting lowercase character data to uppercase.

Arguments

expression: An expression of an ASCII or a Unicode String type.

Return Value

An ASCII or a Unicode String type.

Example

SqlServer.UPPER('AbB')

For more information about the String functions that SqlClient supports, see the documentation for the SQL Server version that you specified in the SqlClient provider manifest:

SQL Server 2000 SQL Server 2005 SQL Server 2008
String Functions (Transact-SQL) String Functions (Transact-SQL) String Functions (Transact-SQL)

See also

System Functions

The .NET Framework Data Provider for SQL Server (SqlClient) provides the following system functions:

Function Description
CHECKSUM ( value, [value, [value]]) Returns the checksum value. CHECKSUM is intended for use in building hash indexes.

Arguments

value: A Boolean, Byte, Int16, Int32, Int64, Single, Decimal, Double, DateTime, String, Binary, or Guid. You can specify one, two or three values.

Return Value

The absolute value of the specified expression.

Example

SqlServer.CHECKSUM(10,100,1000.0)
CURRENT_TIMESTAMP () Produces the current date and time in SQL Server internal format for DateTime values with a precision of 7 in SQL Server 2008 and a precision of 3 in SQL Server 2005.

Return Value

The current system date and time as a DateTime.

Example

SqlServer.CURRENT_TIMESTAMP()
CURRENT_ USER () Returns the name of the current user.

Return Value

An ASCII String.

Example

SqlServer.CURRENT_USER()
DATALENGTH ( expression ) Returns the number of bytes used to represent any expression.

Arguments

expression: A Boolean, Byte, Int16, Int32, Int64, Single, Decimal, Double, DateTime, Time, DateTimeOffset, String, Binary, or Guid.

Return Value

The size of properties as an Int32.

Example

SELECT VALUE SqlServer.DATALENGTH(P.Name)FROM

AdventureWorksEntities.Product AS P
HOST_NAME() Returns the workstation name.

Return Value

A Unicode String.

Example

SqlServer.HOST_NAME()
ISDATE( expression ) Determines whether an input expression is a valid date.

Arguments

expression: A Boolean, Byte, Int16, Int32, Int64, Single, Decimal, Double, DateTime, Time, DateTimeOffset, String, Binary, or Guid.

Return Value

An Int32. One (1) if the input expression is a valid date. Zero (0) otherwise.

Example

SqlServer.ISDATE('1/1/2006')
ISNUMERIC( expression ) Determines whether an expression is a valid numeric type.

Arguments

expression: A Boolean, Byte, Int16, Int32, Int64, Single, Decimal, Double, DateTime, Time, DateTimeOffset, String, Binary, or Guid.

Return Value

An Int32. One (1) if the input expression is a valid date. Zero (0) otherwise.

Example

SqlServer.ISNUMERIC('21')
NEWID() Creates a unique value of type Guid.

Return Value

A Guid.

Example

SqlServer.NEWID()
USER_NAME( id ) Returns a database user name from a specified identification number.

Arguments

expression: An Int32 identification number associated with a database user.

Return Value

A Unicode String.

Example

SqlServer.USER_NAME(0)

For more information about the string functions that SqlClient supports, see the documentation for the SQL Server version that you specified in the SqlClient provider manifest:

SQL Server 2000 SQL Server 2005 SQL Server 2008
System Functions Transact-SQL) System Functions Transact-SQL) System Functions (Transact-SQL)

See also

SqlClient for Entity FrameworkTypes

The .NET Framework Data Provider for SQL Server (SqlClient) provider manifest file includes the list of the provider primitive types, facets for each type, the mappings between the conceptual and storage model primitive types, and the promotion and conversion rules between the conceptual and storage model primitive types.

The following table describes types for SQL Server 2008, SQL Server 2005, and SQL Server 2000 databases and how these types map to conceptual model types. Some new types were introduced in later versions of SQL Server are not supported in the older versions of SQL Server. These types are noted in the table below.

Provider type

name
Provider type

attributes
EDMSimpleType

name
Facets
bit n/a Edm.Boolean n/a
tinyint n/a Edm.Byte n/a
smallint n/a Edm.Int16 n/a
int n/a Edm.Int32 n/a
bigint n/a Edm.Int64 n/a
float n/a Edm.Double n/a
real n/a Edm.Double n/a
decimal n/a Edm.Decimal Precision:

- Minimum: 1

- Maximum: 38

- Default: 18

- Constant: False

Scale:

- Minimum: 0

- Maximum: 38

- Default: 0

- Constant: False
numeric n/a Edm.Decimal Precision:

- Minimum: 1

- Maximum: 38

- Default: 18

- Constant: False

Scale:

- Minimum: 0

- Maximum: 38

- Default: 0

- Constant: False
smallmoney n/a Edm.Decimal Precision:

- Default: 10

- Constant: True

Scale:

- Default: 4

- Constant: True
money n/a Edm.Decimal Precision:

- Default: 19

- Constant: True

Scale:

- Default: 4

- Constant: True
binary n/a Edm.Binary MaxLength:

- Minimum: 1

- Maximum: 8000

- Default: 8000

- Constant: False

FixedLength:

- Default: True

- Constant: True
varbinary n/a Edm.Binary MaxLength:

- Minimum: 1

- Maximum: 8000

- Default: 8000

- Constant: False

FixedLength:

- Default: False

- Constant: True
varbinary(max)

Note: This type is not supported in SQL Server 2000.
n/a Edm.Binary MaxLength:

- Default: 214748364780

- Constant: True

FixedLength:

- Default: False

- Constant: True
image n/a Edm.Binary MaxLength:

- Default: 2147483647

- Constant: True

FixedLength:

- Default: False

- Constant: True
timestamp n/a Edm.Binary MaxLength:

- Default: 8

- Constant: True

FixedLength:

- Default: True

- Constant: True
rowversion n/a Edm.Binary MaxLength:

- Default: 8

- Constant: True

FixedLength:

- Default: True

- Constant: True
smalldatetime n/a Edm.DateTime Precision:

- Default: 0

- Constant: True
datetime n/a Edm.DateTime Precision:

- Default: 3

- Constant: True
date

Note: This type is not supported in SQL Server 2005 and SQL Server 2000.
n/a Edm.DateTime Precision:

- Default: 0

- Constant: False
time

Note: This type is not supported in SQL Server 2005 and SQL Server 2000.
n/a Edm.Time Precision:

- Default: 7

- Constant: False
datetime2

Note: This type is not supported in SQL Server 2005 and SQL Server 2000.
n/a Edm.DateTime Precision:

- Default: 7

- Constant: False
datetimeoffset

Note: This type is not supported in SQL Server 2005 and SQL Server 2000.
n/a Edm.DateTimeOffset Precision:

- Default: 7

- Constant: False
nvarchar

Note: This type is not supported in SQL Server 2000.
n/a Edm.String MaxLength:

- Minimum: 1

- Maximum: 4000

- Default: 4000

- Constant: False

Unicode:

- Default: True

- Constant: True

FixedLength:

- Default: False

- Constant: True
varchar

Note: This type is not supported in SQL Server 2000.
n/a Edm.String MaxLength:

- Minimum: 1

- Maximum: 8000

- Default: 8000

- Constant: False

Unicode:

- Default: False

- Constant: True

FixedLength:

- Default: False

- Constant: True
char n/a Edm.String MaxLength:

- Minimum: 1

- Maximum: 8000

- Default: 8000

- Constant: False

Unicode:

- Default: False

- Constant: True

FixedLength:

- Default: True

- Constant: True
nchar n/a Edm.String MaxLength:

- Minimum: 1

- Maximum: 4000

- Default: 4000

- Constant: False

Unicode:

- Default: True

- Constant: True

FixedLength:

- Default: True

- Constant: True
varchar(max) n/a Edm.String MaxLength:

- Default: 2147483647

- Constant: True

Unicode:

- Default: False

- Constant: True

FixedLength:

- Default: False

- Constant: True
nvarchar(max) n/a Edm.String MaxLength:

- Default: 1073741823

- Constant: True

Unicode:

- Default: True

- Constant: True

FixedLength:

- Default: False

- Constant: True
ntext Equal comparable: False

Order comparable: False
Edm.String MaxLength:

- Default: 1073741823

- Constant: True

Unicode:

- Default: False

- Constant: True

FixedLength:

- Default: False

- Constant: True
text Equal comparable: False

Order comparable: False
Edm.String MaxLength:

- Default: 2147483647

- Constant: True

Unicode:

- Default: False

- Constant: True

FixedLength:

- Default: False

- Constant: True
Unique

identifier
Equal comparable: True

Order comparable: True
Edm.Guid n/a
xml Equal comparable: False

Order comparable: False
Edm.String MaxLength:

- Default: 1073741823

- Constant: True

Unicode:

- Default: True

- Constant: True

FixedLength:

- Default: False

- Constant: True

See also

Known Issues in SqlClient for Entity Framework

This section describes known issues related to the .NET Framework Data Provider for SQL Server (SqlClient).

Trailing Spaces in String Functions

SQL Server ignores trailing spaces in string values. Therefore, passing trailing spaces in the string can lead to unpredictable results, even failures.

If you have to have trailing spaces in your string, you should consider appending a white space character at the end, so that SQL Server does not trim the string. If the trailing spaces are not required, they should be trimmed before they are passed down the query pipeline.

RIGHT Function

If a non-null value is passed as a first argument and 0 is passed as a second argument to RIGHT(nvarchar(max), 0) or RIGHT(varchar(max), 0), a NULL value will be returned instead of an empty string.

CROSS and OUTER APPLY Operators

CROSS and OUTER APPLY operators were introduced in SQL Server 2005. In some cases the query pipeline might produce a Transact-SQL statement that contains CROSS APPLY and/or OUTER APPLY operators. Because some backend providers, including versions of SQL Server earlier than SQL Server 2005, do not support these operators, such queries cannot be executed on these backend providers.

The following are some typical scenarios that might lead to the presence of CROSS APPLY and/or OUTER APPLY operators in the output query:

  • A correlated subquery with paging.

  • An AnyElement over a correlated sub-query, or over a collection produced by navigation.

  • LINQ queries that use grouping methods that accept an element selector.

  • A query in which a CROSS APPLY or an OUTER APPLY is explicitly specified

  • A query that has a DEREF construct over a REF construct.

SKIP Operator

If you are using SQL Server 2000, using SKIP with ORDER BY on non-key columns might return incorrect results. More than the specified number of rows might be skipped if the non-key column has duplicate data in it. This is due to how SKIP is translated for SQL Server 2000. For example, in the following query, more than five rows might be skipped if E.NonKeyColumn has duplicate values:

SELECT [E] FROM Container.EntitySet AS [E] ORDER BY [E].[NonKeyColumn] DESC SKIP 5L  

Targeting the Correct SQL Server Version

The Entity Framework targets the Transact-SQL query based on the SQL Server version that is specified in the ProviderManifestToken attribute of the Schema element in the storage model (.ssdl) file. This version might differ from the version of the actual SQL Server you are connected to. For example, if you are using SQL Server 2005, but your ProviderManifestToken attribute is set to 2008, the generated Transact-SQL query might not execute on the server. For example, a query that uses the new date time types that were introduced in SQL Server 2008 will not execute on earlier versions of the SQL Server. If you are using SQL Server 2005, but your ProviderManifestToken attribute is set to 2000, the generated Transact-SQL query might be less optimized, or you might get an exception that says that the query is not supported. For more information, see the CROSS and OUTER APPLY Operators section, earlier in this topic.

Certain database behaviors depend on the compatibility level set to the database. If your ProviderManifestToken attribute is set to 2005 and your SQL Server version is 2005, but the compatibility level of a database is set to "80" (SQL Server 2000), the generated Transact-SQL will be targeting SQL Server 2005, but might not execute as expected due to the compatibility level setting. For example, you might lose ordering information if a column name in the ORDER BY list matches a column name in the selector.

Nested Queries in Projection

Nested queries in a projection clause might get translated into Cartesian product queries on the server. On some back-end servers, including SLQ Server, this can cause the TempDB table to get quite large. This can decrease server performance.

The following is an example of a nested query in a projection clause:

SELECT c, (SELECT c, (SELECT c FROM AdventureWorksModel.Vendor AS c  ) As Inner2 FROM AdventureWorksModel.JobCandidate AS c  ) As Inner1 FROM AdventureWorksModel.EmployeeDepartmentHistory AS c  

Server Generated GUID Identity Values

The Entity Framework supports server-generated GUID type identity values, but the provider must support returning the server-generated identity value after a row was inserted. Starting with SQL Server 2005, you can return the server-generated GUID type in a SQL Server database through the OUTPUT clause .

See also

Writing an Entity Framework Data Provider

This section discusses how to write an Entity Framework provider to support a data source other than SQL Server. The Entity Framework includes a provider that supports SQL Server.

Introducing the Entity Framework Provider Model

The Entity Framework is database independent, and you can write a provider by using the ADO.NET Provider Model to connect to a diverse set of data sources.

The Entity Framework data provider (built using the ADO.NET Data Provider model) performs the following functions:

  • Maps Entity Data Model (EDM) primitive types to provider types.

  • Exposes provider-specific functions.

  • Generates provider-specific commands for a given DbQueryCommandTree to support Entity Framework queries.

  • Generates provider-specific update commands for a given DbModificationCommandTree to support updates through the Entity Framework.

  • Exposes mapping files for the store schema definition, to support generation of a model based on a database.

  • Exposes metadata (tables and views, for example) via a conceptual model.

b42a7a5c-0ac0-4911-86be-0460a78760ba

Sample

See the Entity Framework Sample Provider for a sample of an Entity Framework provider that supports a data source other than SQL Server.

In This Section

SQL Generation

Modification SQL Generation

Provider Manifest Specification

See also

SQL Generation

When you write a provider for the Entity Framework, you must translate Entity Framework command trees into SQL that a specific database can understand, such as Transact-SQL for SQL Server or PL/SQL for Oracle. In this section, you will learn how to develop a SQL generation component (for SELECT queries) for an Entity Framework provider. For information about insert, update, and delete queries, see Modification SQL Generation.

To understand this section, you should be familiar with the Entity Framework and the ADO.NET Provider Model. You should also understand command trees and DbExpression.

The Role of the SQL Generation Module

The SQL generation module of an Entity Framework provider translates a given query command tree into a single SQL SELECT statement that targets a SQL:1999-compliant database. The generated SQL should have as few nested queries as possible. The SQL generation module should not simplify the output query command tree. The Entity Framework will do this, for example by eliminating joins and collapsing consecutive filter nodes.

The DbProviderServices class is the starting point for accessing the SQL generation layer to convert command trees into DbCommand.

In This Section

The Shape of the Command Trees

Generating SQL from Command Trees - Best Practices

SQL Generation in the Sample Provider

See also

The Shape of the Command Trees

The SQL generation module is responsible for generating a backend specific SQL query based on a given input query command tree expression. This section discusses the characteristics, properties, and structure of the query command trees.

Query Command Trees Overview

A query command tree is an object model representation of a query. Query command trees serve two purposes:

  • To express an input query that is specified against the Entity Framework.

  • To express an output query that is given to a provider and describes a query against the backend.

Query command trees support richer semantics than SQL:1999 compliant queries, including support for working with nested collections and type operations, like checking whether an entity is of a particular type, or filtering sets based on a type.

The DBQueryCommandTree.Query property is the root of the expression tree that describes the query logic. The DBQueryCommandTree.Parameters property contains a list of parameters that are used in the query. The expression tree is composed of DbExpression objects.

A DbExpression object represents some computation. Several kinds of expressions are provided by the Entity Framework for composing query expressions, including constants, variables, functions, constructors, and standard relational operators like filter and join. Every DbExpression object has a ResultType property that represents the type of the result produced by that expression. This type is expressed as a TypeUsage.

Shapes of the Output Query Command Tree

Output query command trees closely represent relational (SQL) queries and adhere to much stricter rules than those that apply to query command trees. They typically contain constructs that are easily translated to SQL.

Input command trees are expressed against the conceptual model, which supports navigation properties, associations among entities, and inheritance. Output command trees are expressed against the storage model. Input command trees allow you to project nested collections, but output command trees do not.

Output query command trees are built using a subset of the available DbExpression objects and even some expressions in that subset have restricted usage.

Type operations, like checking whether a given expression is of a particular type or filtering sets based on a type, are not present in output command trees.

In output command trees, only expressions that return Boolean values are used for projections and only for predicates in expressions requiring a predicate, like a filter or a case statement.

The root of an output query command trees is a DbProjectExpression object.

Expression Types Not Present in Output Query Command Trees

The following expression types are not valid in an output query command tree and do not need to be handled by providers:

  • DbDerefExpression

  • DbEntityRefExpression

  • DbRefKeyExpression

  • DbIsOfExpression

  • DbOfTypeExpression

  • DbRefExpression

  • DbRelationshipNavigationExpression

  • DbTreatExpression

Expression Restrictions and Notes

Many expressions can only be used in a restricted manner in output query command trees:

DbFunctionExpression

The following function types can be passed:

  • Canonical functions that are recognized by the Edm namespace.

  • Built-in (store) functions that are recognized by the BuiltInAttribute.

  • User-defined functions.

Canonical functions (see Canonical Functions for more information) are specified as part of the Entity Framework, and providers should supply implementations for canonical functions based on those specifications. Store functions are based on the specifications in the corresponding provider manifest. User defined functions are based on specifications in the SSDL.

Also, functions having the NiladicFunction attribute have no arguments and should be translated without the parenthesis at the end. That is, to <functionName> instead of <functionName>().

DbNewInstanceExpression

DbNewInstanceExpression can only occur in the following two cases:

  • As the Projection property of DbProjectExpression. When used as such the following restrictions apply:

    • The result type must be a row type.

    • Each of its arguments is an expression that produces a result with a primitive type. Typically, each argument is a scalar expression, like a PropertyExpression over a DbVariableReferenceExpression, a function invocation, or an arithmetic computation of the DbPropertyExpression over a DbVariableReferenceExpression or a function invocation. However, an expression representing a scalar subquery can also occur in the list of arguments for a DbNewInstanceExpression. An expression that represents a scalar subquery is an expression tree that represents a subquery that returns exactly one row and one column of a primitive type with a DbElementExpression object root

  • With a collection return type, in which case it defines a new collection of the expressions provided as arguments.

DbVariableReferenceExpression

A DbVariableReferenceExpression has to be a child of DbPropertyExpression node.

DbGroupByExpression

The Aggregates property of a DbGroupByExpression can only have elements of type DbFunctionAggregate. There are no other aggregate types.

DbLimitExpression

The property Limit can only be a DbConstantExpression or a DbParameterReferenceExpression. Also property WithTies is always false as of version 3.5 of the .NET Framework.

DbScanExpression

When used in output command trees, the DbScanExpression effectively represents a scan over a table, a view, or a store query, represented by EntitySetBase::Target.

If the metadata property "Defining Query" of the target is non-null, then it represents a query, the query text for which is provided in that metadata property in the provider’s specific language (or dialect) as specified in the store schema definition.

Otherwise, the target represents a table or a view. Its schema prefix is either in the "Schema" metadata property, if not null, otherwise is the entity container name. The table or view name is either the "Table" metadata property, if not null, otherwise the Name property of the entity set base.

All these properties originate from the definition of the corresponding EntitySet in the store schema definition file (the SSDL).

Using Primitive Types

When primitive types are referenced in output command trees, they are typically referenced in the conceptual model's primitive types. However, for certain expressions, providers need the corresponding store primitive type. Examples of such expressions include DbCastExpression and possibly DbNullExpression, if the provider needs to cast the null to the corresponding type. In these cases, providers should do the mapping to the provider type based on the primitive type kind and its facets.

See also

Generating SQL from Command Trees - Best Practices

Output query command trees closely model queries expressible in SQL. However, there are certain common challenges for provider writers when generating SQL from an output command tree. This topic discusses these challenges. In the next topic, the sample provider shows how to address these challenges.

Group DbExpression Nodes in a SQL SELECT Statement

A typical SQL statement has a nested structure of the following shape:

SQL
SELECT …
FROM …
WHERE …
GROUP BY …
ORDER BY …

One or more clauses may be empty. A nested SELECT statement could occur in any of the lines.

A possible translation of a query command tree into a SQL SELECT statement would produce one subquery for every relational operator. However, that would lead to unnecessary nested subqueries that would be difficult to read. On some data stores, the query may perform poorly.

As an example, consider the following query command tree

Project (
a.x,
   a = Filter(
      b.y = 5,
      b = Scan("TableA")
   )
)

An inefficient translation would produce:

SQL
SELECT a.x
FROM (   SELECT *
         FROM TableA as b
         WHERE b.y = 5) as a

Note that every relational expression node becomes a new SQL SELECT statement.

Therefore, it is important to aggregate as many expression nodes as possible into a single SQL SELECT statement while preserving correctness.

The result of such aggregation for the example presented above would be:

SQL
SELECT b.x
FROM TableA as b
WHERE b.y = 5

Flatten Joins in a SQL SELECT Statement

One case of aggregating multiple nodes into a single SQL SELECT statement is aggregating multiple join expressions into a single SQL SELECT statement. DbJoinExpression represents a single join between two inputs. However, as part of a single SQL SELECT statement, more than one join can be specified. In that case the joins are performed in the order specified.

Left spine joins, (joins that appear as a left child of another join) can be more easily flattened into a single SQL SELECT statement. For example, consider the following query command tree:

InnerJoin(
   a = LeftOuterJoin(
   b = Extent("TableA")
   c = Extent("TableB")
   ON b.y = c.x ),
   d = Extent("TableC")
   ON a.b.y = d.z
)

This can be correctly translated into:

SQL
SELECT *
FROM TableA as b
LEFT OUTER JOIN TableB as c ON b.y = c.x
INNER JOIN TableC as d ON b.y = d.z

However, non-left spine joins cannot easily be flattened, and you should not try to flatten them. For example, the joins in the following query command tree:

InnerJoin(
   a = Extent("TableA")
   b = LeftOuterJoin(
   c = Extent("TableB")
   d = Extent("TableC")
   ON c.y = d.x),
   ON a.z = b.c.y
)

Would be translated to a SQL SELECT statement with a sub-query.

SQL
SELECT *
FROM TableA as a
INNER JOIN (SELECT *
   FROM TableB as c
   LEFT OUTER JOIN TableC as d
   ON c.y = d.x) as b
ON b.y = d.z

Input Alias Redirecting

To explain input alias redirecting, consider the structure of the relational expressions, such as DbFilterExpression, DbProjectExpression, DbCrossJoinExpression, DbJoinExpression, DbSortExpression, DbGroupByExpression, DbApplyExpression, and DbSkipExpression.

Each of these types has one or more Input properties that describe an input collection, and a binding variable corresponding to each input is used to represent each element of that input during a collection traversal. The binding variable is used when referring to the input element, for example in the Predicate property of a DbFilterExpression or the Projection property of a DbProjectExpression.

When aggregating more relational expression nodes into a single SQL SELECT statement, and evaluating an expression that is part of a relational expression (for example part of the Projection property of a DbProjectExpression) the binding variable that it uses may not be the same as the alias of the input, as multiple expression bindings would have to be redirected to a single extent. This problem is called alias renaming.

Consider the first example in this topic. If doing the naïve translation and translating the Projection a.x (DbPropertyExpression(a, x)), it is correct to translate it into a.x because we have aliased the input as "a" to match the binding variable. However, when aggregating both the nodes into a single SQL SELECT statement, you need to translate the same DbPropertyExpression into b.x, as the input has been aliased with "b".

Join Alias Flattening

Unlike any other relational expression in an output command tree, the DbJoinExpression outputs a result type that is a row consisting of two columns, each of which corresponds to one of the inputs. When a DbPropertyExpression is built to access a scalar property originating from a join, it is over another DbPropertyExpression.

Examples include "a.b.y" in example 2 and "b.c.y" in example 3. However in the corresponding SQL statements these are referred as "b.y". This re-aliasing is called join alias flattening.

Column Name and Extent Alias Renaming

If a SQL SELECT query that has a join has to be completed with a projection, when enumerating all the participating columns from the inputs, a name collision may occur, as more than one input may have the same column name. Use a different name for the column to avoid the collision.

Also, when flattening joins, participating tables (or subqueries) may have colliding aliases in which case these need to be renamed.

Avoid SELECT *

Do not use SELECT * to select from base tables. The storage model in an Entity Framework application may only include a subset of the columns that are in the database table. In this case, SELECT * may produce an incorrect result. Instead, you should specify all participating columns by using the column names from the result type of the participating expressions.

Reuse of Expressions

Expressions may be reused in the query command tree passed by the Entity Framework. Do not assume that each expression appears only once in the query command tree.

Mapping Primitive Types

When mapping conceptual (EDM) types to provider types, you should map to the widest type (Int32) so that all possible values fit. Also, avoid mapping to types that cannot be used for many operations, like BLOB types (for example, ntext in SQL Server).

See also

SQL Generation in the Sample Provider

The Entity Framework Sample Provider demonstrates the new components of ADO.NET Data Providers that support the Entity Framework. It works with a SQL Server 2005 database and is implemented as a wrapper for the System.Data.SqlClient ADO.NET 2.0 Data Provider.

The SQL Generation module of the Sample Provider (located under the SQL Generation folder, except for the file DmlSqlGenerator.cs) takes an input DbQueryCommandTree and produces a single SQL SELECT statement.

See also

Architecture and Design

The SQL generation module in the Sample Provider is implemented as a visitor on the expression tree that represents the command tree. The generation is done in a single pass over the expression tree.

The nodes of the tree are processed from the bottom up. First, an intermediate structure is produced: SqlSelectStatement or SqlBuilder, both implementing ISqlFragment. Next, the string SQL statement is produced from that structure. There are two reasons for the intermediate structure:

  • Logically, a SQL SELECT statement is populated out of order. The nodes that participate in the FROM clause are visited before the nodes that participate in the WHERE, GROUP BY, and the ORDER BY clause.

  • To rename aliases, you must identify all used aliases to avoid collisions during renaming. To defer the renaming choices in SqlBuilder, use Symbol objects to represent the columns that are candidates for renaming.

Diagram

In the first phase, while visiting the expression tree, expressions are grouped into SqlSelectStatements, joins are flattened, and join aliases are flattened. During this pass, Symbol objects represent columns or input aliases that may be renamed.

In the second phase, while producing the actual string, aliases are renamed.

Data Structures

This section discusses the types used in the Sample Provider that you use to build a SQL statement.

ISqlFragment

This section covers the classes that implement the ISqlFragment interface, which serves two purposes:

  • A common return type for all the visitor methods.

  • Gives a method to write the final SQL string.

C#
internal interface ISqlFragment {
   void WriteSql(SqlWriter writer, SqlGenerator sqlGenerator);
}

SqlBuilder

SqlBuilder is a gathering device for the final SQL string, similar to StringBuilder. It consists of the strings that make up the final SQL, along with ISqlFragments that can be converted into strings.

C#
internal sealed class SqlBuilder : ISqlFragment {
   public void Append(object s)
   public void AppendLine()
   public bool IsEmpty
}

SqlSelectStatement

SqlSelectStatement represents a canonical SQL SELECT statement of the shape "SELECT … FROM .. WHERE … GROUP BY … ORDER BY".

Each of the SQL clauses is represented by a StringBuilder. In addition, it tracks whether Distinct has been specified and whether the statement is topmost. If the statement is not topmost, the ORDER BY clause is omitted unless the statement also has a TOP clause.

FromExtents contains the list of inputs for the SELECT statement. There is usually just one element in this. SELECT statements for joins may temporarily have more than one element.

If the SELECT statement is created by a Join node, SqlSelectStatement maintains a list of all the extents that have been flattened in the join in AllJoinExtents. OuterExtents represents outer references of the SqlSelectStatement and is used for input alias renaming.

C#
internal sealed class SqlSelectStatement : ISqlFragment {
   internal bool IsDistinct { get, set };
   internal bool IsTopMost

   internal List<Symbol> AllJoinExtents { get, set };
   internal List<Symbol> FromExtents { get};
   internal Dictionary<Symbol, bool> OuterExtents { get};

   internal TopClause Top { get, set };

   internal SqlBuilder Select {get};
   internal SqlBuilder From
   internal SqlBuilder Where
   internal SqlBuilder GroupBy
   public SqlBuilder OrderBy
}

TopClause

TopClause represents the TOP expression in a SqlSelectStatement. The TopCount property indicates how many TOP rows should be selected. When WithTies is true, the TopClause was built from a DbLimitExpression.

C#
class TopClause : ISqlFragment {
   internal bool WithTies {get}
   internal ISqlFragment TopCount {get}
   internal TopClause(ISqlFragment topCount, bool withTies)
   internal TopClause(int topCount, bool withTies)
}

Symbols

The Symbol-related classes and the symbol table perform input alias renaming, join alias flattening, and column alias renaming.

The Symbol class represents an extent, a nested SELECT statement, or a column. It is used instead of an actual alias to allow for renaming after it has been used and it also carries additional information for the artifact it represents (like the type).

C#
class Symbol : ISqlFragment {
   internal Dictionary<string, Symbol> Columns {get}
   internal bool NeedsRenaming {get, set}
   internal bool IsUnnest {get, set}   //not used

   public string Name{get}
   public string NewName {get,set}
   internal TypeUsage Type {get, set}

   public Symbol(string name, TypeUsage type)
}

Name stores the original alias for the represented extent, nested SELECT statement, or a column.

NewName stores the alias that will be used in the SQL SELECT statement. It is originally set to Name, and only renamed if needed when generating the final string query.

Type is only useful for symbols representing extents and nested SELECT statements.

SymbolPair

The SymbolPair class addresses record flattening.

Consider a property expression D(v, "j3.j2.j1.a.x") where v is a VarRef, j1, j2, j3 are joins, a is an extent, and x is a columns.

This has to be translated eventually into {j'}.{x'}. The source field represents the outermost SqlStatement, representing a join expression (say j2); this is always a Join symbol. The column field moves from one join symbol to the next until it stops at a non-join symbol. This is returned when visiting a DbPropertyExpression but is never added to a SqlBuilder.

C#
class SymbolPair : ISqlFragment {
   public Symbol Source;
   public Symbol Column;
   public SymbolPair(Symbol source, Symbol column)
}

JoinSymbol

A Join symbol is a Symbol that represents a nested SELECT statement with a join or a join input.

C#
internal sealed class JoinSymbol : Symbol {
   internal List<Symbol> ColumnList {get, set}
   internal List<Symbol> ExtentList {get}
   internal List<Symbol> FlattenedExtentList {get, set}
   internal Dictionary<string, Symbol> NameToExtent {get}
   internal bool IsNestedJoin {get, set}

   public JoinSymbol(string name, TypeUsage type, List<Symbol> extents)
}

ColumnList represents the list of columns in the SELECT clause if this symbol represents a SQL SELECT statement. ExtentList is the list of extents in the SELECT clause. If the join has multiple extents flattened at the top level, FlattenedExtentList tracks the extents to ensure that extent aliases are renamed correctly.

NameToExtent has all the extents in ExtentList as a dictionary. IsNestedJoin is used to determine whether a JoinSymbol is an ordinary join symbol or one that has a corresponding SqlSelectStatement.

All the lists are set exactly once and then used for lookups or enumeration.

SymbolTable

SymbolTable is used to resolve variable names to Symbols. SymbolTable is implemented as a stack with a new entry for each scope. Lookups search from the top of the stack to the bottom until an entry is found.

C#
internal sealed class SymbolTable {
   internal void EnterScope()
   internal void ExitScope()
   internal void Add(string name, Symbol value)
   internal Symbol Lookup(string name)
}

There is only one SymbolTable per one instance of the Sql Generation module. Scopes are entered and exited for each relational node. All symbols in earlier scopes are visible to later scopes unless hidden by other symbols with the same name.

Global State for the Visitor

To assist in renaming of aliases and columns, maintain a list of all the column names (AllColumnNames) and extent aliases (AllExtentNames) that have been used in the first pass over the query tree. The symbol table resolves variable names to Symbols. IsVarRefSingle is only used for verification purposes, it is not strictly necessary.

The two stacks used via CurrentSelectStatement and IsParentAJoin are used to pass "parameters" from parent to child nodes, since the visitor pattern does not allow us to pass parameters.

C#
internal Dictionary<string, int> AllExtentNames {get}
internal Dictionary<string, int> AllColumnNames {get}
SymbolTable symbolTable = new SymbolTable();
bool isVarRefSingle = false;

Stack<SqlSelectStatement> selectStatementStack;
private SqlSelectStatement CurrentSelectStatement{get}

Stack<bool> isParentAJoinStack;
private bool IsParentAJoin{get}

Common Scenarios

This section discusses common provider scenarios.

Grouping Expression Nodes into SQL Statements

A SqlSelectStatement is created when the first relational node is encountered (typically a DbScanExpression extent) when visiting the tree from the bottom up. To produce a SQL SELECT statement with as few nested queries as possible, aggregate as many of its parent nodes as possible in that SqlSelectStatement.

The decision of whether a given (relational) node can be added to the current SqlSelectStatement (the one returned when visiting the input) or if a new statement needs to be started is computed by the method IsCompatible and depends on what is already in the SqlSelectStatement, which depends on what nodes were below the given node.

Typically, if SQL statement clauses are evaluated after clauses where the nodes being considered for merging are not empty, the node cannot be added to the current statement. For example, if the next node is a Filter, that node can be incorporated into the current SqlSelectStatement only if the following is true:

  • The SELECT list is empty. If the SELECT list is not empty, the select list was produced by a node preceding the filter and the predicate may refer to columns produced by that SELECT list.

  • The GROUPBY is empty. If the GROUPBY is not empty, adding the filter would mean filtering before grouping, which is not correct.

  • The TOP clause is empty. If the TOP clause is not empty, adding the filter would mean filtering before doing TOP, which is not correct.

This does not apply to non-relational nodes like DbConstantExpression or arithmetic expressions, because these are always included as part of an existing SqlSelectStatement.

Also, when encountering the root of join tree (a join node that does not have a join parent), a new SqlSelectStatement is started. All of its left spine join children are aggregated into that SqlSelectStatement.

Whenever a new SqlSelectStatement is started, and the current one is added to the input, the current SqlSelectStatement may need to be completed by adding projection columns (a SELECT clause) if one does not exist. This is done with the method AddDefaultColumns, which looks at the FromExtents of the SqlSelectStatement and adds all the columns that the list of extents represented by FromExtents brings in scope to the list of projected columns. This is done, because at that point, it is unknown which columns are referenced by the other nodes. This can be optimized to only project the columns that can later be used.

Join Flattening

The IsParentAJoin property helps determine whether a given join can be flattened. In particular, IsParentAJoin returns true only for the left child of a join and for each DbScanExpression that is an immediate input to a join, in which case that child node reuses the same SqlSelectStatement that the parent would later use. For more information, see "Join Expressions".

Input Alias Redirecting

Input alias redirecting is accomplished with the symbol table.

To explain input alias redirecting, refer to the first example in Generating SQL from Command Trees - Best Practices. There "a" needed to be redirected to "b" in the projection.

When a SqlSelectStatement object is created, the extent that is the input to the node is put in the From property of the SqlSelectStatement. A Symbol (<symbol_b>) is created based on the input binding name ("b") to represent that extent and "AS " + <symbol_b> is appended to the From Clause. The symbol is also added to the FromExtents property.

The symbol is also added to the symbol table to link the input binding name to it ("b", <symbol_b>).

If a subsequent node reuses that SqlSelectStatement, it adds an entry to the symbol table to link its input binding name to that symbol. In our example, the DbProjectExpression with the input binding name of "a" would reuse the SqlSelectStatement and add ("a", < symbol_b>) to the table.

When expressions reference the input binding name of the node that is reusing the SqlSelectStatement, that reference is resolved using the symbol table to the correct redirected symbol. When "a" from "a.x" is resolved while visiting the DbVariableReferenceExpression representing "a" it will resolve to the Symbol <symbol_b>.

Join Alias Flattening

Join alias flattening is achieved when visiting a DbPropertyExpression as described in the section titled DbPropertyExpression.

Column Name and Extent Alias Renaming

The issue of column name and extent alias renaming is addressed by using symbols that only get substituted with aliases in the second phase of the generation described in the section titled Second Phase of SQL Generation: Generating the String Command.

First Phase of the SQL Generation: Visiting the Expression Tree

This section describes the first phase of SQL generation, when the expression representing the query is visited and an intermediate structure is produced, either a SqlSelectStatement or a SqlBuilder.

This section describes the principles of visiting different expression node categories, and details of visiting specific expression types.

Relational (Non-Join) Nodes

The following expression types support non-join nodes:

  • DbDistinctExpression

  • DbFilterExpression

  • DbGroupByExpression

  • DbLimitExpression

  • DbProjectExpression

  • DbSkipExpression

  • DbSortExpression

Visiting these nodes follows the following pattern:

  1. Visit the relational input and get the resulting SqlSelectStatement. The input to a relational node could be one of the following:

    • A relational node, including an extent (a DbScanExpression, for example). Visiting such a node returns a SqlSelectStatement.

    • A set operation expression (UNION ALL, for example). The result has to be wrapped in brackets and put in the FROM clause of a new SqlSelectStatement.

  2. Check whether the current node can be added to the SqlSelectStatement produced by the input. The section titled Grouping Expressions into SQL Statements describes this. If not,

    • Pop the current SqlSelectStatement object.

    • Create a new SqlSelectStatement object and add the popped SqlSelectStatement as the FROM of the new SqlSelectStatement object.

    • Put the new object on top of the stack.

  3. Redirect the input expression binding to the correct symbol from the input. This information is maintained in the SqlSelectStatement object.

  4. Add a new SymbolTable scope.

  5. Visit the non-input part of the expression (for example, Projection and Predicate).

  6. Pop all the objects added to the global stacks.

DbSkipExpression not have a direct equivalent in SQL. Logically, it is translated into:

SQL
SELECT Y.x1, Y.x2, ..., Y.xn
FROM (
   SELECT X.x1, X.x2, ..., X.xn, row_number() OVER (ORDER BY sk1, sk2, ...) AS [row_number]
   FROM input as X
   ) as Y
WHERE Y.[row_number] > count
ORDER BY sk1, sk2, ...

Join Expressions

The following are considered join expressions and they are processed in a common way, by the VisitJoinExpression method:

  • DbApplyExpression

  • DbJoinExpression

  • DbCrossJoinExpression

The following are the visit steps:

First, before visiting the children, IsParentAJoin is invoked to check whether the join node is a child of a join along a left spine. If it returns false, a new SqlSelectStatement is started. In that sense, joins are visited differently from the rest of the nodes, as the parent (the join node) creates the SqlSelectStatement for the children to possibly use.

Second, process the inputs one at a time. For each input:

  1. Visit the input.

  2. Post process the result of visiting the input by invoking ProcessJoinInputResult, which is responsible for maintaining the symbol table after visiting a child of a join expression and possibly finishing the SqlSelectStatement produced by the child. The child's result could be one of the following:

    • A SqlSelectStatement different from the one to which the parent will be added. In such case, it may need to be completed by adding default columns. If the input was a Join, you need to create a new join symbol. Otherwise, create a normal symbol.

    • An extent (a DbScanExpression, for example), in which case it is simply added to the list of inputs of the parent’s SqlSelectStatement.

    • Not a SqlSelectStatement, in which case it is wrapped with brackets.

    • The same SqlSelectStatement to which the parent is added. In such case, the symbols in the FromExtents list need to be replaced with a single new JoinSymbol representing them all.

    • For the first three cases, AddFromSymbol is called to add the AS clause, and update the symbol table.

Third, the join condition (if any) is visited.

Set Operations

The set operations DbUnionAllExpression, DbExceptExpression, and DbIntersectExpression are processed by the method VisitSetOpExpression. It creates a SqlBuilder of the shape

XML
<leftSqlSelectStatement> <setOp> <rightSqlSelectStatement>

Where <leftSqlSelectStatement> and <rightSqlSelectStatement> are SqlSelectStatements obtained by visiting each of the inputs, and <setOp> is the corresponding operation (UNION ALL for example).

DbScanExpression

If visited in a join context (as an input to a join that is a left child of another join), DbScanExpression returns a SqlBuilder with the target SQL for the corresponding target, which is either a defining query, table, or a view. Otherwise, a new SqlSelectStatement is created with the FROM field set to correspond to the corresponding target.

DbVariableReferenceExpression

The visit of a DbVariableReferenceExpression returns the Symbol corresponding to that variable reference expression based on a look up in the symbol table.

DbPropertyExpression

Join alias flattening is identified and processed when visiting a DbPropertyExpression.

The Instance property is first visited and the result is a Symbol, a JoinSymbol, or a SymbolPair. Here is how these three cases are handled:

  • If a JoinSymbol is returned, than its NameToExtent property contains a symbol for the needed property. If the join symbol represents a nested join, a new Symbol pair is returned with the join symbol to track the symbol that would be used as the instance alias, and the symbol representing the actual property for further resolving.

  • If a SymbolPair is returned and the Column part is a join symbol, a join symbol is again returned, but now the column property is updated to point to the property represented by the current property expression. Otherwise a SqlBuilder is returned with the SymbolPair source as the alias, and the symbol for the current property as the column.

  • If a Symbol is returned, the Visit method returns a SqlBuilder method with that instance as the alias, and the property name as column name.

DbNewInstanceExpression

When used as the Projection property of DbProjectExpression, DbNewInstanceExpression produces a comma-separated list of the arguments to represent the projected columns.

When DbNewInstanceExpression has a collection return type, and defines a new collection of the expressions provided as arguments, the following three cases are handled separately:

  • If DbNewInstanceExpression has DbElementExpression as the only argument, it is translated as follows:

  • NewInstance(Element(X)) =>  SELECT TOP 1 …FROM X
    

If DbNewInstanceExpression has no arguments (represents an empty table), DbNewInstanceExpression is translated into:

SQL
SELECT CAST(NULL AS <primitiveType>) as X
FROM (SELECT 1) AS Y WHERE 1=0

Otherwise DbNewInstanceExpression builds a union-all ladder of the arguments:

SQL
SELECT <visit-result-arg1> as X
UNION ALL SELECT <visit-result-arg2> as X
UNION ALL …
UNION ALL SELECT <visit-result-argN> as X

DbFunctionExpression

Canonical and built-in functions are processed the same way: if they need special handling (TRIM(string) to LTRIM(RTRIM(string), for example), the appropriate handler is invoked. Otherwise they are translated to FunctionName(arg1, arg2, ..., argn).

Dictionaries are used to keep track of which functions need special handling and their appropriate handlers.

User-defined functions are translated to NamespaceName.FunctionName(arg1, arg2, ..., argn).

DbElementExpression

The method that visits DbElementExpression is only invoked for visiting a DbElementExpression when used to represent a scalar subquery. Therefore, DbElementExpression translates into a complete SqlSelectStatement and adds brackets around it.

DbQuantifierExpression

Depending on the expression type (Any or All), DbQuantifierExpression is translated it as:

Any(input, x) => Exists(Filter(input,x))
All(input, x) => Not Exists(Filter(input, not(x))

DbNotExpression

In some cases it is possible to collapse the translation of DbNotExpression with its input expression. For example:

Not(IsNull(a)) =>  "a IS NOT NULL"
Not(All(input, x) => Not (Not Exists(Filter(input, not(x))) => Exists(Filter(input, not(x))

The reason the second collapse is performed is because inefficiencies were introduced by the provider when translating DbQuantifierExpression of type All. Thus the Entity Framework could not have done the simplification.

DbIsEmptyExpression

DbIsEmptyExpression is translated as:

IsEmpty(input) = Not Exists(input)

Second Phase of SQL Generation: Generating the String Command

When generating a string SQL command, the SqlSelectStatement produces actual aliases for the symbols, which addresses the issue of column name and extent alias renaming.

Extent alias renaming occurs while writing the SqlSelectStatement object into a string. First create a list of all the aliases used by the outer extents. Each symbol in the FromExtents (or AllJoinExtents if it is non-null), gets renamed if it collides with any of the outer extents. If renaming is needed, it will not conflict with any of the extents collected in AllExtentNames.

Column renaming occurs while writing a Symbol object to a string. AddDefaultColumns in the first phase has determined if a certain column symbol has to be renamed. In the second phase only the rename occurs making sure that the name produced does not conflict with any name used in AllColumnNames

To produce unique names both for extent aliases and for columns, use <existing_name>_n where n is the smallest alias that has not been used yet. The global list of all aliases increases the need for cascading renames.

See also

Walkthrough: SQL Generation

This topic illustrates how SQL generation occurs in the Sample Provider. The following Entity SQL query uses the model that is included with the sample provider:

SQL
SELECT  j1.ProductId, j1.ProductName, j1.CategoryName, j2.ShipCountry, j2.ProductId
FROM (  SELECT P.ProductName, P.ProductId, P.Category.CategoryName
        FROM NorthwindEntities.Products AS P) as j1
INNER JOIN (SELECT OD.ProductId, OD.Order.ShipCountry as ShipCountry
            FROM NorthwindEntities.OrderDetails AS OD) as j2
            ON j1.ProductId == j2.ProductId

The query produces the following output command tree that is passed to the provider:

DbQueryCommandTree
|_Parameters
|_Query : Collection{Record['C1'=Edm.Int32, 'ProductID'=Edm.Int32, 'ProductName'=Edm.String, 'CategoryName'=Edm.String, 'ShipCountry'=Edm.String, 'ProductID1'=Edm.Int32]}
  |_Project
    |_Input : 'Join4'
    | |_InnerJoin
    |   |_Left : 'Join1'
    |   | |_LeftOuterJoin
    |   |   |_Left : 'Extent1'
    |   |   | |_Scan : dbo.Products
    |   |   |_Right : 'Extent2'
    |   |   | |_Scan : dbo.Categories
    |   |   |_JoinCondition
    |   |     |_
    |   |       |_Var(Extent1).CategoryID
    |   |       |_=
    |   |       |_Var(Extent2).CategoryID
    |   |_Right : 'Join3'
    |   | |_LeftOuterJoin
    |   |   |_Left : 'Extent3'
    |   |   | |_Scan : dbo.OrderDetails
    |   |   |_Right : 'Join2'
    |   |   | |_LeftOuterJoin
    |   |   |   |_Left : 'Extent4'
    |   |   |   | |_Scan : dbo.Orders
    |   |   |   |_Right : 'Extent5'
    |   |   |   | |_Scan : dbo.InternationalOrders
    |   |   |   |_JoinCondition
    |   |   |     |_
    |   |   |       |_Var(Extent4).OrderID
    |   |   |       |_=
    |   |   |       |_Var(Extent5).OrderID
    |   |   |_JoinCondition
    |   |     |_
    |   |       |_Var(Extent3).OrderID
    |   |       |_=
    |   |       |_Var(Join2).Extent4.OrderID
    |   |_JoinCondition
    |     |_
    |       |_Var(Join1).Extent1.ProductID
    |       |_=
    |       |_Var(Join3).Extent3.ProductID
    |_Projection
      |_NewInstance : Record['C1'=Edm.Int32, 'ProductID'=Edm.Int32, 'ProductName'=Edm.String, 'CategoryName'=Edm.String, 'ShipCountry'=Edm.String, 'ProductID1'=Edm.Int32]
        |_Column : 'C1'
        | |_1
        |_Column : 'ProductID'
        | |_Var(Join4).Join1.Extent1.ProductID
        |_Column : 'ProductName'
        | |_Var(Join4).Join1.Extent1.ProductName
        |_Column : 'CategoryName'
        | |_Var(Join4).Join1.Extent2.CategoryName
        |_Column : 'ShipCountry'
        | |_Var(Join4).Join3.Join2.Extent4.ShipCountry
        |_Column : 'ProductID1'
          |_Var(Join4).Join3.Extent3.ProductID

This topic describes how to translate this output command tree into the following SQL statements.

SQL
SELECT
1 AS [C1],
[Extent1].[ProductID] AS [ProductID],
[Extent1].[ProductName] AS [ProductName],
[Extent2].[CategoryName] AS [CategoryName],
[Join3].[ShipCountry] AS [ShipCountry],
[Join3].[ProductID] AS [ProductID1]
FROM   [dbo].[Products] AS [Extent1]
LEFT OUTER JOIN [dbo].[Categories] AS [Extent2] ON [Extent1].[CategoryID] = [Extent2].[CategoryID]
INNER JOIN
(SELECT [Extent3].[OrderID] AS [OrderID1], [Extent3].[ProductID] AS [ProductID], [Extent3].[UnitPrice] AS [UnitPrice], [Extent3].[Quantity] AS [Quantity], [Extent3].[Discount] AS [Discount], [Join2].[OrderID2], [Join2].[CustomerID], [Join2].[EmployeeID], [Join2].[OrderDate], [Join2].[RequiredDate], [Join2].[ShippedDate], [Join2].[Freight], [Join2].[ShipName], [Join2].[ShipAddress], [Join2].[ShipCity], [Join2].[ShipRegion], [Join2].[ShipPostalCode], [Join2].[ShipCountry], [Join2].[OrderID3], [Join2].[CustomsDescription], [Join2].[ExciseTax]
FROM  [dbo].[OrderDetails] AS [Extent3]
LEFT OUTER JOIN
      (SELECT [Extent4].[OrderID] AS [OrderID2], [Extent4].[CustomerID] AS [CustomerID], [Extent4].[EmployeeID] AS [EmployeeID], [Extent4].[OrderDate] AS [OrderDate], [Extent4].[RequiredDate] AS [RequiredDate], [Extent4].[ShippedDate] AS [ShippedDate], [Extent4].[Freight] AS [Freight], [Extent4].[ShipName] AS [ShipName], [Extent4].[ShipAddress] AS [ShipAddress], [Extent4].[ShipCity] AS [ShipCity], [Extent4].[ShipRegion] AS [ShipRegion], [Extent4].[ShipPostalCode] AS [ShipPostalCode], [Extent4].[ShipCountry] AS [ShipCountry], [Extent5].[OrderID] AS [OrderID3], [Extent5].[CustomsDescription] AS [CustomsDescription], [Extent5].[ExciseTax] AS [ExciseTax]
FROM  [dbo].[Orders] AS [Extent4]
LEFT OUTER JOIN [dbo].[InternationalOrders] AS [Extent5] ON [Extent4].[OrderID] = [Extent5].[OrderID]
      ) AS [Join2] ON [Extent3].[OrderID] = [Join2].[OrderID2]
   ) AS [Join3] ON [Extent1].[ProductID] = [Join3].[ProductID]

First Phase of SQL Generation: Visiting the Expression Tree

The following figure illustrates the initial empty state of the visitor. Throughout this topic, only the properties relevant to the walkthrough explanation are shown.

Diagram

When the Project node is visited, VisitInputExpression is called over its input (Join4), which triggers the visit of Join4 by the method VisitJoinExpression. Because this is a topmost join, IsParentAJoin returns false and a new SqlSelectStatement (SelectStatement0) is created and pushed on the SELECT statement stack. Also, a new scope (scope0) is entered in the symbol table. Before the first (left) input of the join is visited, 'true' is pushed on the IsParentAJoin stack. Right before Join1, which is the left input of Join4, is visited, the state of the visitor is as shown in the next figure.

Diagram

When the join visit method is invoked over Join4, IsParentAJoin is true, thus it reuses the current select statement SelectStatement0. A new scope is entered (scope1). Before visiting its left child, Extent1, another true is pushed on the IsParentAJoin stack.

When Extent1 is visited, because IsParentAJoin returns true, it returns a SqlBuilder containing "[dbo].[Products]". The control returns to the method visiting Join4. An entry is popped from IsParentAJoin, and ProcessJoinInputResult is called, which appends the result of visiting Extent1 to the From clause of SelectStatement0. A new from symbol, symbol_Extent1, for the input binding name "Extent1" is created, added to the FromExtents of SelectStatement0, and also "As" and symbol_Extent1 are appended to the from clause. A new entry is added to AllExtentNames for "Extent1" with the value of 0. A new entry is added to the current scope in the symbol table to associate "Extent1" with its symbol symbol_Extent1. Symbol_Extent1 is also added to the AllJoinExtents of the SqlSelectStatement.

Before the right input of Join1 is visited, "LEFT OUTER JOIN" is added to the From clause of SelectStatement0. Because the right input is a Scan expression, true is again pushed to the IsParentAJoin stack. The state before visiting the right input as shown in the next figure.

Diagram

The right input is processed in the same way as the left input. The state after visiting the right input is shown in the next figure.

Diagram

Next "false" is pushed on the IsParentAJoin stack and the join condition Var(Extent1).CategoryID == Var(Extent2).CategoryID is processed. Var(Extent1) is resolved to <symbol_Extent1> after a look up in the symbol table. Because the instance is resolved to a simple Symbol, as a result of processing Var(Extent1).CategoryID, a SqlBuilder with <symbol1>."CategoryID" is returned. Similarly the other side of the comparison is processed, and the result of visiting the join condition is appended to the FROM clause of SelectStatement1 and the value "false" is popped from the IsParentAJoin stack.

With this, Join1 has completely been processed, and a scope is popped from the symbol table.

Control returns to processing Join4, the parent of Join1. Because the child reused the Select statement, the Join1 extents are replaced with a single Join symbol <joinSymbol_Join1>. Also a new entry is added to the symbol table to associate Join1 with <joinSymbol_Join1>.

The next node to be processed is Join3, the second child of Join4. As it is a right child, "false" is pushed to the IsParentAJoin stack. The state of the visitor at this point is illustrated in the next figure.

Diagram

For Join3, IsParentAJoin returns false and needs to start a new SqlSelectStatement (SelectStatement1) and push it on the stack. Processing continues as it did with the previous the previous joins, a new scope is pushed on the stack and the children are processed. The left child is an Extent (Extent3) and the right child is a join (Join2) which also needs to start a new SqlSelectStatement: SelectStatement2. The children on Join2 are Extents as well and are aggregated into SelectStatement2.

The state of the visitor right after Join2 is visited, but before its post-processing (ProcessJoinInputResult) is done is shown in the next figure:

Diagram

In the previous figure, SelectStatement2 is shown as free floating because it was popped out of the stack, but not yet post processed by the parent. It needs to be added to the FROM part of the parent, but it is not a complete SQL statement without a SELECT clause. So, at this point, the default columns (all the columns produced by its inputs) are added to the select list by the method AddDefaultColumns. AddDefaultColumns iterates over the symbols in FromExtents and for each symbol adds all the columns brought in scope. For a simple symbol, it looks at the symbol type to retrieve all its properties to be added. It also populates the AllColumnNames dictionary with the column names. The completed SelectStatement2 is appended to the FROM clause of SelectStatement1.

Next, a new join symbol is created to represent Join2, it is marked as a nested join and added to the AllJoinExtents of SelectStatement1 and added to the symbol table. Now the join condition of Join3, Var(Extent3).OrderID = Var(Join2).Extent4.OrderID, needs to be processed. Processing of the left hand side is similar to the join condition of Join1. However, the processing of the right and side "Var(Join2).Extent4.OrderID" is different because join flattening is required.

The next figure shows the state of the visitor right before the DbPropertyExpression "Var(Join2).Extent4.OrderID" is processed.

Consider how "Var(Join2).Extent4.OrderID" is visited. First, the instance property "Var(Join2).Extent4" is visited, which is another DbPropertyExpression and first visits its instance "Var(Join2)". In the top most scope in the symbol table, "Join2" resolves to <joinSymbol_join2>. In the visit method for DbPropertyExpression processing "Var(Join2).Extent4" notice that a join symbol was returned when visiting the instance and flattening is required.

Since it is a nested join, we look up the property "Extent4" in the NameToExtent dictionary of the join symbol, resolve it to <symbol_Extent4> and return a new SymbolPair(<joinSymbol_join2>, <symbol_Extent4>). Since a symbol pair is returned from the processing of the instance of "Var(Join2).Extent4.OrderID", the property "OrderID" is resolved from the ColumnPart of that symbol pair (<symbol_Extent4>), which has a list of the columns of the extent it represents. So, "Var(Join2).Extent4.OrderID" is resolved to { <joinSymbol_Join2>, ".", <symbol_OrderID>}.

The join condition of Join4 is similarly processed. The control returns to the VisitInputExpression method that processed the top most project. Looking at the FromExtents of the returned SelectStatement0, the input is identified as a join, and removes the original extents and replaces them with a new extent with just the Join symbol. The symbol table is also updated and next the projection part of the Project is processed. The resolving of the properties and the flattening of the join extents is as described earlier.

Diagram

Finally, the following SqlSelectStatement is produced:

SELECT:
  "1", " AS ", "[C1]",
  <symbol_Extent1>, ".", "[ProductID]", " AS ", "[ProductID]",
  <symbol_Extent1>, ".", "[ProductName]", " AS ", "[ProductName]",
  <symbol_Extent2>, ".", "[CategoryName]", " AS ", "[CategoryName]",
  <joinSymbol_Join3>, ".", <symbol_ShipCountry>, " AS ", "[ShipCountry]",
  <joinSymbol_Join3>, ".", <symbol_ProductID>, " AS ", "[ProductID1]"
FROM: "[dbo].[Products]", " AS ", <symbol_Extent1>,
        "LEFT OUTER JOIN ""[dbo].[Categories]", " AS ", <symbol_Extent2>, " ON ", <symbol_Extent1>, ".", "[CategoryID]", " = ", <symbol_Extent2>, ".", "[CategoryID]",
        "INNER JOIN ",
        " (", SELECT:
           <symbol_Extent3>, ".", "[OrderID]", " AS ", <symbol_OrderID>, ",
              <symbol_Extent3>, ".", "[ProductID]", " AS ", <symbol_ProductID>, ...,
         <joinSymbol_Join2>, ".", <symbol_OrderID_2>, ", ",
           <joinSymbol_Join2>, ".", <symbol_CustomerID>, ....,
        <joinSymbol_Join2>, ".", <symbol_OrderID_3>,
<joinSymbol_Join2>, ".", <symbol_CustomsDescription>,
<joinSymbol_Join2>, ".", <symbol_ExciseTax>
FROM: "[dbo].[OrderDetails]", " AS ", <symbol_Extent3>,
"LEFT OUTER JOIN ",
" (", SELECT:
<symbol_Extent4>, ".", "[OrderID]", " AS ", <symbol_OrderID_2>,
<symbol_Extent4>, ".", "[CustomerID]", " AS ", <symbol_CustomerID>, ...
<symbol_Extent5>, ".", "[OrderID]", " AS ", <symbol_OrderID_3>,
<symbol_Extent5>, ".", "[CustomsDescription]", " AS ", <symbol_CustomsDescription>,
<symbol_Extent5>, ".", "[ExciseTax]", " AS ", <symbol_ExciseTax>
FROM: "[dbo].[Orders]", " AS ", <symbol_Extent4>,
"LEFT OUTER JOIN ", , "[dbo].[InternationalOrders]", " AS ", <symbol_Extent5>,
" ON ", <symbol_Extent4>, ".", "[OrderID]", " = ", , <symbol_Extent5>, ".", "[OrderID]"
" )", " AS ", <joinSymbol_Join2>, " ON ", , , <symbol_Extent3>, ".", "[OrderID]", " = ", , <joinSymbol_Join2>, ".", <symbol_OrderID_2>
" )", " AS ", <joinSymbol_Join3>, " ON ", , , <symbol_Extent1>, ".", "[ProductID]", " = ", , <joinSymbol_Join3>, ".", <symbol_ProductID>

Second Phase of SQL Generation: Generating the String Command

The second phase produces actual names for the symbols, and we only focus on the symbols representing columns named "OrderID", as in this case a conflict needs to be resolved. These are highlighted in the SqlSelectStatement. Note that the suffixes used in the figure are only to emphasize that these are different instances, not to represent any new names, as at this stage their final names (possibly different form the original names) have not been assigned yet.

The first symbol found that needs to be renamed is <symbol_OrderID>. Its new name is assigned as "OrderID1", 1 is marked as the last used suffix for "OrderID" and the symbol is marked as not needing renaming. Next, the first usage of <symbol_OrderID_2> is found. It is renamed to use the next available suffix ("OrderID2") and again marked as not needing renaming, so that next time it is used it does not get renamed. This is done for <symbol_OrderID_3> too.

At the end of the second phase, the final SQL statement is generated.

See also

Modification SQL Generation

This section discusses how to develop a modification SQL generation module for your (SQL:1999-compliant database) provider. This module is responsible for translating a modification command tree into the appropriate SQL INSERT, UPDATE or DELETE statements.

For information about SQL generation for select statements, see SQL Generation.

Overview of Modification Command Trees

The modification SQL generation module generates database-specific modification SQL statements based on a given input DbModificationCommandTree.

A DbModificationCommandTree is an object model representation of a modification DML operation (an insert, an update, or a delete operation), inheriting from DbCommandTree. There are three implementations of DbModificationCommandTree:

  • DbInsertCommandTree

  • DbUpdateCommandTree

  • DbDeleteCommandTree

DbModificationCommandTree and its implementations that are produced by the Entity Framework always represent a single row operation. This section describes these types with their constraints in the .NET Framework version 3.5.

Diagram

DbModificationCommandTree has a Target property that represents the target set for the modification operation. The Target’s Expression property, which defines the input set is always DbScanExpression. A DbScanExpression can either represent a table or a view, or a set of data defined with a query if the metadata property "Defining Query" of its Target is non-null.

A DbScanExpression that represents a query could only reach a provider as a target of modification if the set was defined by using a defining query in the model but no function was provided for the corresponding modification operation. Providers may not be able to support such a scenario (SqlClient, for example, does not).

DbInsertCommandTree represents a single row insert operation expressed as a command tree.

C#
public sealed class DbInsertCommandTree : DbModificationCommandTree {
   public IList<DbModificationClause> SetClauses { get }
   public DbExpression Returning { get }
}

DbUpdateCommandTree represents a single-row update operation expressed as a command tree.

DbDeleteCommandTree represents a single row delete operation expressed as a command tree.

Restrictions on Modification Command Tree Properties

The following information and restrictions apply to the modification command tree properties.

Returning in DbInsertCommandTree and DbUpdateCommandTree

When non-null, Returning indicates that the command returns a reader. Otherwise, the command should return a scalar value indicating the number of rows affected (inserted or updated).

The Returning value specifies a projection of results to be returned based on the inserted or the updated row. It can only be of type DbNewInstanceExpression representing a row, with each of its arguments being a DbPropertyExpression over a DbVariableReferenceExpression representing a reference to the Target of the corresponding DbModificationCommandTree. The properties represented by the DbPropertyExpressions used in the property Returning are always store generated or computed values. In DbInsertCommandTree, Returning is not null when at least one property of the table in which the row is being inserted is specified as store generated or computed (marked as StoreGeneratedPattern.Identity or StoreGeneratedPattern.Computed in the ssdl). In DbUpdateCommandTrees, Returning is not null when at least one property of the table in which the row is being updated is specified as store computed (marked as StoreGeneratedPattern.Computed in the ssdl).

SetClauses in DbInsertCommandTree and DbUpdateCommandTree

SetClauses specifies the list of insert or update set clauses that define the insert or update operation.

The elements of the list are specified as type DbModificationClause, which specifies a single clause in an insert or update modification operation. DbSetClause inherits from DbModificationClause and specifies the clause in a modification operation that sets the value of a property. Beginning in version 3.5 of the .NET Framework, all elements in SetClauses are of type SetClause.

Property specifies the property that should be updated. It is always a DbPropertyExpression over a DbVariableReferenceExpression, which represents a reference to the Target of the corresponding DbModificationCommandTree.

Value specifies the new value with which to update the property. It is either of type DbConstantExpression or DbNullExpression.

Predicate in DbUpdateCommandTree and DbDeleteCommandTree

Predicate specifies the predicate used to determine which members of the target collection should be updated or deleted. It is an expression tree built of the following subset of DbExpressions:

  • DbComparisonExpression of kind Equals, with the right child being a DbPropertyExpression as restricted below and the left child a DbConstantExpression.

  • DbConstantExpression

  • DbIsNullExpression over a DbPropertyExpression as restricted below

  • DbPropertyExpression over a DbVariableReferenceExpression representing a reference to the Target of the corresponding DbModificationCommandTree.

  • DbAndExpression

  • DbNotExpression

  • DbOrExpression

Modification SQL Generation in the Sample Provider

The Entity Framework Sample Provider demonstrates the components of ADO.NET Data Providers that support the Entity Framework. It targets a SQL Server 2005 database and is implemented as a wrapper on top of System.Data.SqlClient ADO.NET 2.0 Data Provider.

The modification SQL generation module of the sample provider (located in the file SQL Generation\DmlSqlGenerator.cs) takes an input DbModificationCommandTree and produces a single modification SQL statement possibly followed by a select statement to return a reader if specified by the DbModificationCommandTree. Note that the shape of the commands generated is affected by the target SQL Server database.

Helper Classes: ExpressionTranslator

ExpressionTranslator serves as a common lightweight translator for all modification command tree properties of type DbExpression. It supports translation of only the expression types to which the properties of the modification command tree are constrained and is built with the particular constraints in mind.

The following information discusses visiting specific expression types (nodes with trivial translations are omitted).

DbComparisonExpression

When the ExpressionTranslator is constructed with preserveMemberValues = true, and when the constant to the right is a DbConstantExpression (instead of DbNullExpression), it associates the left operand (a DbPropertyExpressions) with that DbConstantExpression. That is used if a return Select statement needs to be generated to identify the affected row.

DbConstantExpression

For each visited constant a parameter is created.

DbPropertyExpression

Given that the Instance of the DbPropertyExpression always represents the input table, unless the generation has created an alias (which only happens in update scenarios when a table variable is used), no alias needs to be specified for the input; the translation defaults to the property name.

Generating an Insert SQL Command

For a given DbInsertCommandTree in the sample provider, the generated insert command follows one of the two insert templates below.

The first template has a command to perform the insert given the values in the list of SetClauses, and a SELECT statement to return the properties specified in the Returning property for the inserted row if the Returning property was not null. The predicate element "@@ROWCOUNT > 0" is true if a row was inserted. The predicate element "keyMemberI = keyValueI | scope_identity()" takes the shape "keyMemberI = scope_identity()" only if keyMemberI is a store-generated key, because scope_identity() returns the last identity value inserted into an identity (store-generated) column.

SQL
-- first insert Template
INSERT <target>   [ (setClauseProperty0, .. setClausePropertyN)]
VALUES (setClauseValue0, .. setClauseValueN) |  DEFAULT VALUES

[SELECT <returning>
 FROM <target>
 WHERE @@ROWCOUNT > 0 AND keyMember0 = keyValue0 AND .. keyMemberI =  keyValueI | scope_identity()  .. AND  keyMemberN = keyValueN]

The second template is needed if the insert specifies inserting a row where the primary key is store-generated but is not an integer type and therefore can't be used with scope_identity()). It is also used if there is a compound store-generated key.

SQL
-- second insert template
DECLARE @generated_keys TABLE [(keyMember0, … keyMemberN)

INSERT <target>   [ (setClauseProperty0, .. setClausePropertyN)]
 OUTPUT inserted.KeyMember0, …, inserted.KeyMemberN INTO @generated_keys
 VALUES (setClauseValue0, .. setClauseValueN) |  DEFAULT VALUES

[SELECT <returning_over_t>
 FROM @generated_keys  AS g
JOIN <target> AS t ON g.KeyMember0 = t.KeyMember0 AND … g.KeyMemberN = t.KeyMemberN
 WHERE @@ROWCOUNT > 0

The following is an example that uses the model that is included with the sample provider. It generates an insert command from a DbInsertCommandTree.

The following code inserts a Category:

C#
using (NorthwindEntities northwindContext = new NorthwindEntities()) {
   Category c = new Category();
   c.CategoryName = "Test Category";
   c.Description = "A new category for testing";
   northwindContext.AddObject("Categories", c);
   northwindContext.SaveChanges();
}

This code produces the following command tree, which is passed to the provider:

DbInsertCommandTree
|_Parameters
|_Target : 'target'
| |_Scan : dbo.Categories
|_SetClauses
| |_DbSetClause
| | |_Property
| | | |_Var(target).CategoryName
| | |_Value
| |   |_'Test Category'
| |_DbSetClause
| | |_Property
| | | |_Var(target).Description
| | |_Value
| |   |_'A new category for testing'
| |_DbSetClause
|   |_Property
|   | |_Var(target).Picture
|   |_Value
|     |_null
|_Returning
  |_NewInstance : Record['CategoryID'=Edm.Int32]
    |_Column : 'CategoryID'
      |_Var(target).CategoryID

The store command that the sample provider produces is the following SQL statement:

SQL
insert [dbo].[Categories]([CategoryName], [Description], [Picture])
values (@p0, @p1, null)
select [CategoryID]
from [dbo].[Categories]
where @@ROWCOUNT > 0 and [CategoryID] = scope_identity()

Generating an Update SQL Command

For a given DbUpdateCommandTree, the generated update command is based on the following template:

SQL
-- UPDATE Template
UPDATE <target>
SET setClauseProperty0 = setClauseValue0, .. setClausePropertyN = setClauseValueN  | @i = 0
WHERE <predicate>

[SELECT <returning>
 FROM <target>
 WHERE @@ROWCOUNT > 0 AND keyMember0 = keyValue0 AND .. keyMemberI =  keyValueI | scope_identity()  .. AND  keyMemberN = keyValueN]

The set clause has the fake set clause ("@i = 0") only if no set clauses are specified. This is to ensure that any store-computed columns are recomputed.

Only if the Returning property is not null, a select statement is generated to return the properties specified in the Returning property.

The following example uses the model that is included with the sample provider to generate an update command.

The following user code updates a Category:

C#
using (NorthwindEntities northwindContext = new NorthwindEntities()) {
   Category c = northwindContext.Categories.Where(i => i.CategoryName == "Test Category").First();
   c.CategoryName = "New test name";
   northwindContext.SaveChanges();
}

This user code produces the following command tree, which is passed to the provider:

DbUpdateCommandTree
|_Parameters
|_Target : 'target'
| |_Scan : dbo.Categories
|_SetClauses
| |_DbSetClause
|   |_Property
|   | |_Var(target).CategoryName
|   |_Value
|     |_'New test name'
|_Predicate
| |_
|   |_Var(target).CategoryID
|   |_=
|   |_10
|_Returning

The sample provider produces the following store command:

SQL
update [dbo].[Categories]
set [CategoryName] = @p0
where ([CategoryID] = @p1)

Generating a Delete SQL Command

For a given DbDeleteCommandTree, the generated DELETE command is based on the following template:

SQL
-- DELETE Template
DELETE <target>
WHERE <predicate>

The following example uses the model that is included with the sample provider to generate a delete command.

The following user code deletes a Category:

C#
using (NorthwindEntities northwindContext = new NorthwindEntities()) {
   Category c = northwindContext.Categories.Where(i => i.CategoryName == "New test name").First();
   northwindContext.DeleteObject(c);
   northwindContext.SaveChanges();
}

This user code produces the following command tree, which is passed to the provider.

DbDeleteCommandTree
|_Parameters
|_Target : 'target'
| |_Scan : dbo.Categories
|_Predicate
  |_
    |_Var(target).CategoryID
    |_=
    |_10

The following store command is produced by the sample provider:

SQL
delete [dbo].[Categories]
where ([CategoryID] = @p0)

See also

Provider Manifest Specification

This section discusses how a data store provider can support the types and functions in the data store.

Entity Services operates independently of a specific data store provider yet still allows a data provider to explicitly define how models, mappings, and queries interact with an underlying data store. Without a layer of abstraction, Entity Services could only be targeted at a specific data store or data provider.

Types that the provider supports are directly or indirectly supported by the underlying database. These types are not necessarily the exact store types, but the types the provider uses to support the Entity Framework. Provider/store types are described in the Entity Data Model (EDM) terms.

Parameter and return types for the functions supported by the data store are specified in EDM terms.

Requirements

The Entity Framework and the data store need to be able to pass data back and forth in known types without any data loss or truncation.

The provider manifest must be loadable by tools at design time without having to open a connection to the data store.

The Entity Framework is case sensitive, but the underlying data store may not be. When EDM artifacts (identifiers and type names, for example) are defined and used in the manifest, they must use the Entity Framework case sensitivity. If data store elements that may be case sensitive appear in the provider manifest, that casing needs to be maintained in the provider manifest.

The Entity Framework requires a provider manifest for all data providers. If you try to use a provider that does not have a provider manifest with the Entity Framework, you will get an error.

The following table describes the kinds of exceptions the Entity Framework would throw when exceptions arise through provider interaction:

Issue Exception
The Provider does not support GetProviderManifest in DbProviderServices. ProviderIncompatibleException
Missing provider manifest: the provider returns null when attempting to retrieve the provider manifest. ProviderIncompatibleException
Invalid provider manifest: the provider returns invalid XML when attempting to retrieve the provider manifest. ProviderIncompatibleException

Scenarios

A provider should support the following scenarios:

Writing a Provider with Symmetric Type Mapping

You can write a provider for the Entity Framework where each store type maps to a single EDM type, regardless of the mapping direction. For a provider type that has very simple mapping that corresponds with an EDM type, you can use a symmetric solution because the type system is simple or matches EDM types.

You can use the simplicity of their domain and produce a static declarative provider manifest.

You write an XML file that has two sections:

  • A list of provider types expressed in terms of the "EDM counterpart" of a store type or function. Store types have counterpart EDM types. Store functions have corresponding EDM functions. For example, varchar is a SQL Server type but the corresponding EDM type is string.

  • A list of functions supported by the provider where parameter and return types are expressed in EDM terms.

Writing a Provider with Asymmetric Type Mapping

When writing a data store provider for the Entity Framework, the EDM-to-provider type mapping for some types may be different from provider-to-EDM type mapping. For instance, unbounded EDM PrimitiveTypeKind.String may map to nvarchar(4000) on the provider, while nvarchar(4000) maps to the EDM PrimitiveTypeKind.String(MaxLength=4000).

You write an XML file that has two sections:

  • A list of provider types expressed in EDM terms and define mapping for both direction: EDM-to-provider and provider-to-EDM.

  • A list of functions supported by the provider where parameter and return types are expressed in EDM terms.

Provider Manifest Discoverability

The manifest is used indirectly by several component types in Entity Services (for example Tools or Query) but more directly leveraged by metadata through the use of the data store metadata loader.

dfb3d02b-7a8c-4d51-ac5a-a73d8aa145e6

However, a given provider may support different stores or different versions of the same store. Therefore, a provider must report a different manifest for each supported data store.

Provider Manifest Token

When a data store connection is opened, the provider can query for information to return the right manifest. This may not be possible in offline scenarios where connection information is not available or when it is not possible to connect to the store. Identify the manifest by using the ProviderManifestToken attribute of the Schema element in the .ssdl file. There is no required format for this attribute; the provider chooses the minimum information needed to identify a manifest without opening a connection to the store.

For example:

XML
<Schema Namespace="Northwind" Provider="System.Data.SqlClient" ProviderManifestToken="2005" xmlns:edm="http://schemas.microsoft.com/ado/2006/04/edm/ssdl" xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">  

Provider Manifest Programming Model

Providers derive from DbXmlEnabledProviderManifest, which allows them to specify their manifests declaratively. The following illustration shows the class hierarchy of a provider:

None

Discoverability API

The provider manifest is loaded by the Store Metadata loader (StoreItemCollection), either by using a data store connection or a provider manifest token.

Using a Data Store Connection

When the data store connection is available, call DbProviderServices.GetProviderManifestToken to return the token that is passed to the GetProviderManifest method, which returns DbProviderManifest. This method delegates to the provider's implementation of GetDbProviderManifestToken.

C#
public string GetProviderManifestToken(DbConnection connection);  
public DbProviderManifest GetProviderManifest(string manifestToken);  

Using a Provider Manifest Token

For the offline scenario, the token is picked from SSDL representation. The SSDL allows you to specify a ProviderManifestToken (see Schema Element (SSDL) for more information). For example, if a connection cannot be opened, the SSDL has a provider manifest token that specifies information about the manifest.

public DbProviderManifest GetProviderManifest(string manifestToken);  

Provider Manifest Schema

The schema of information defined for each provider contains the static information to be consumed by metadata:

XML
<?xml version="1.0" encoding="utf-8"?>  
<xs:schema elementFormDefault="qualified"  
   xmlns:xs="http://www.w3.org/2001/XMLSchema"  
   targetNamespace="http://schemas.microsoft.com/ado/2006/04/edm/providermanifest"  
   xmlns:pm="http://schemas.microsoft.com/ado/2006/04/edm/providermanifest">  
  
  <xs:element name="ProviderManifest">  
    <xs:complexType>  
      <xs:sequence>  
        <xs:element name="Types" type="pm:TTypes" minOccurs="1" maxOccurs="1" />  
        <xs:element name="Functions" type="pm:TFunctions" minOccurs="0" maxOccurs="1"/>  
      </xs:sequence>  
      <xs:attribute name="Namespace" type="xs:string" use="required"/>  
    </xs:complexType>  
  </xs:element>  
  <xs:complexType name="TVersion">  
    <xs:attribute name="Major" type="xs:int" use="required" />  
    <xs:attribute name="Minor" type="xs:int" use="required" />  
    <xs:attribute name="Build" type="xs:int" use="required" />  
    <xs:attribute name="Revision" type="xs:int" use="required" />  
  </xs:complexType>  
  
  <xs:complexType name="TIntegerFacetDescription">  
    <xs:attribute name="Minimum" type="xs:int" use="optional" />  
    <xs:attribute name="Maximum" type="xs:int" use="optional" />  
    <xs:attribute name="DefaultValue" type="xs:int" use="optional" />  
    <xs:attribute name="Constant" type="xs:boolean" default="false" />  
  </xs:complexType>  
  
  <xs:complexType name="TBooleanFacetDescription">  
    <xs:attribute name="DefaultValue" type="xs:boolean" use="optional" />  
    <xs:attribute name="Constant" type="xs:boolean" default="true" />  
  </xs:complexType>  
  
  <xs:complexType name="TDateTimeFacetDescription">  
    <xs:attribute name="Constant" type="xs:boolean" default="false" />  
  </xs:complexType>  
  
  <xs:complexType name="TFacetDescriptions">  
    <xs:choice maxOccurs="unbounded">  
      <xs:element name="Precision" minOccurs="0" maxOccurs="1" type="pm:TIntegerFacetDescription"/>  
      <xs:element name="Scale" minOccurs="0" maxOccurs="1" type="pm:TIntegerFacetDescription"/>  
      <xs:element name="MaxLength" minOccurs="0" maxOccurs="1" type="pm:TIntegerFacetDescription"/>  
      <xs:element name="Unicode" minOccurs="0" maxOccurs="1" type="pm:TBooleanFacetDescription"/>  
      <xs:element name="FixedLength" minOccurs="0" maxOccurs="1" type="pm:TBooleanFacetDescription"/>  
    </xs:choice>  
  </xs:complexType>  
  
  <xs:complexType name="TType">  
    <xs:sequence>  
      <xs:element name="FacetDescriptions" type="pm:TFacetDescriptions" minOccurs="0" maxOccurs="1"/>  
    </xs:sequence>  
    <xs:attribute name="Name" type="xs:string" use="required"/>  
    <xs:attribute name="PrimitiveTypeKind" type="pm:TPrimitiveTypeKind" use="required" />  
  </xs:complexType>  
  
  <xs:complexType name="TTypes">  
    <xs:sequence>  
      <xs:element name="Type" type="pm:TType" minOccurs="0" maxOccurs="unbounded"/>  
    </xs:sequence>  
  </xs:complexType>  
  
  <xs:attributeGroup name="TFacetAttribute">  
    <xs:attribute name="Precision" type="xs:int" use="optional"/>  
    <xs:attribute name="Scale" type="xs:int" use="optional"/>  
    <xs:attribute name="MaxLength" type="xs:int" use="optional"/>  
    <xs:attribute name="Unicode" type="xs:boolean" use="optional"/>  
    <xs:attribute name="FixedLength" type="xs:boolean" use="optional"/>  
  </xs:attributeGroup>  
  
  <xs:complexType name="TFunctionParameter">  
    <xs:attribute name="Name" type="xs:string" use="required" />  
    <xs:attribute name="Type" type="xs:string" use="required" />  
    <xs:attributeGroup ref="pm:TFacetAttribute" />  
    <xs:attribute name="Mode" type="pm:TParameterDirection" use="required" />  
  </xs:complexType>  
  
  <xs:complexType name="TReturnType">  
    <xs:attribute name="Type" type="xs:string" use="required" />  
    <xs:attributeGroup ref="pm:TFacetAttribute" />  
  </xs:complexType>  
  
  <xs:complexType name="TFunction">  
    <xs:choice minOccurs="0" maxOccurs ="unbounded">  
      <xs:element name ="ReturnType" type="pm:TReturnType" minOccurs="0" maxOccurs="1" />  
      <xs:element name="Parameter" type="pm:TFunctionParameter" minOccurs="0" maxOccurs="unbounded"/>  
    </xs:choice>  
    <xs:attribute name="Name" type="xs:string" use="required" />  
    <xs:attribute name="Aggregate" type="xs:boolean" use="optional" />  
    <xs:attribute name="BuiltIn" type="xs:boolean" use="optional" />  
    <xs:attribute name="StoreFunctionName" type="xs:string" use="optional" />  
    <xs:attribute name="NiladicFunction" type="xs:boolean" use="optional" />  
    <xs:attribute name="ParameterTypeSemantics" type="pm:TParameterTypeSemantics" use="optional" default="AllowImplicitConversion" />  
  </xs:complexType>  
  
  <xs:complexType name="TFunctions">  
    <xs:sequence>  
      <xs:element name="Function" type="pm:TFunction" minOccurs="0" maxOccurs="unbounded"/>  
    </xs:sequence>  
  </xs:complexType>  
  
  <xs:simpleType name="TPrimitiveTypeKind">  
    <xs:restriction base="xs:string">  
      <xs:enumeration value="Binary"/>  
      <xs:enumeration value="Boolean"/>  
      <xs:enumeration value="Byte"/>  
      <xs:enumeration value="Decimal"/>  
      <xs:enumeration value="DateTime"/>  
      <xs:enumeration value="Time"/>  
      <xs:enumeration value="DateTimeOffset"/>          
      <xs:enumeration value="Double"/>  
      <xs:enumeration value="Guid"/>  
      <xs:enumeration value="Single"/>  
      <xs:enumeration value="SByte"/>  
      <xs:enumeration value="Int16"/>  
      <xs:enumeration value="Int32"/>  
      <xs:enumeration value="Int64"/>  
      <xs:enumeration value="String"/>  
    </xs:restriction>  
  </xs:simpleType>  
  
  <xs:simpleType name="TParameterDirection">  
    <xs:restriction base="xs:string">  
      <xs:enumeration value="In"/>  
      <xs:enumeration value="Out"/>  
      <xs:enumeration value="InOut"/>  
    </xs:restriction>  
  </xs:simpleType>  
  
  <xs:simpleType name="TParameterTypeSemantics">  
    <xs:restriction base="xs:string">  
      <xs:enumeration value="ExactMatchOnly" />  
      <xs:enumeration value="AllowImplicitPromotion" />  
      <xs:enumeration value="AllowImplicitConversion" />  
    </xs:restriction>  
  </xs:simpleType>  
</xs:schema>  

Types Node

The Types node in the provider manifest contains information about the Types that are supported natively by the data store or through the provider.

Type Node

Each Type node defines a provider type in terms of EDM. The Type node describes the name of the provider type, and information related to the model type it maps to and facets to describe that type mapping.

In order to express this type information in the provider manifest, each TypeInformation declaration must define several facet descriptions for each Type:

Attribute Name Data Type Required Default Value Description
Name String Yes n/a Provider-specific data type name
PrimitiveTypeKind PrimitiveTypeKind Yes n/a EDM type name
Function Node

Each Function defines a single function available through the provider.

Attribute Name Data Type Required Default Value Description
Name String Yes n/a Identifier/name of the function
ReturnType String No Void The EDM return type of the function
Aggregate Boolean No False True if the function is an aggregate function
BuiltIn Boolean No True True if the function is built into the data store
StoreFunctionName String No <Name> Function Name in the data store. Allows for a level of redirection of function names.
NiladicFunction Boolean No False True if the function does not require parameters and is called without any parameters
ParameterType

Semantics
ParameterSemantics No AllowImplicit

Conversion
Choice of how the query pipeline should deal with parameter type substitution:

- ExactMatchOnly
- AllowImplicitPromotion
- AllowImplicitConversion

Parameters Node

Each function has a collection of one or more Parameter nodes.

Attribute Name Data Type Required Default Value Description
Name String Yes n/a Identifier/name of the parameter.
Type String Yes n/a The EDM type of the parameter.
Mode Parameter

Direction
Yes n/a Direction of parameter:

- in
- out
- inout
Namespace Attribute

Each data store provider must define a namespace or group of namespaces for information defined in the manifest. This namespace can be used in Entity SQL queries to resolve names of functions and types. For instance: SqlServer. That namespace must be different from the canonical namespace, EDM, defined by Entity Services for standard functions to be supported by Entity SQL queries.

See also

Development and Deployment Considerations

Topics in this section address issues to consider when developing or deploying an application that is based on the ADO.NET Entity Framework.

In This Section

Security Considerations

Performance Considerations

Migration Considerations

Deployment Considerations

See also

Security Considerations

This topic describes security considerations that are specific to developing, deploying, and running Entity Framework applications. You should also follow recommendations for creating secure .NET Framework applications. For more information, see Security Overview.

General Security Considerations

The following security considerations apply to all applications that use the Entity Framework.

Use only trusted data source providers.

To communicate with the data source, a provider must do the following:

  • Receive the connection string from the Entity Framework.

  • Translate the command tree to the data source's native query language.

  • Assemble and return result sets.

During the logon operation, information that is based on the user password is passed to the server through the network libraries of the underlying data source. A malicious provider can steal user credentials, generate malicious queries, or tamper with the result set.

Encrypt your connection to protect sensitive data.

The Entity Framework does not directly handle data encryption. If users access data over a public network, your application should establish an encrypted connection to the data source to increase security. For more information, see the security-related documentation for your data source. For a SQL Server data source, see Encrypting Connections to SQL Server.

Secure the connection string.

Protecting access to your data source is one of the most important goals when securing an application. A connection string presents a potential vulnerability if it is not secured or if it is improperly constructed. When you store connection information in plain text or persist it in memory, you risk compromising your entire system. The following are the recommended methods for securing connection strings:

  • Use Windows Authentication with a SQL Server data source.

    When you use Windows Authentication to connect to a SQL Server data source, the connection string does not contain logon and password information.

  • Encrypt configuration file sections using protected configuration.

    ASP.NET provides a feature called protected configuration that enables you to encrypt sensitive information in a configuration file. Although primarily designed for ASP.NET, you can also use protected configuration to encrypt sections of configuration files in Windows applications. For a detailed description of the new protected configuration capabilities, see Encrypting Configuration Information Using Protected Configuration.

  • Store connection strings in secured configuration files.

    You should never embed connection strings in your source code. You can store connection strings in configuration files, which eliminates the need to embed them in your application's code. By default, the Entity Data Model Wizard stores connection strings in the application configuration file. You must secure this file to prevent unauthorized access.

  • Use connection string builders when dynamically creating connections.

    If you must construct connection strings at runtime, use the EntityConnectionStringBuilder class. This string builder class helps prevent connection string injection attacks by validating and escaping invalid input information. For more information, see How to: Build an EntityConnection Connection String. Also use the appropriate string builder class to construct the data source connection string that is part of the Entity Framework connection string. For information about connection string builders for ADO.NET providers, see Connection String Builders.

For more information, see Protecting Connection Information.

Do not expose an EntityConnection to untrusted users.

An EntityConnection object exposes the connection string of the underlying connection. A user with access to an EntityConnection object can also change the ConnectionState of the underlying connection. The EntityConnection class is not thread safe.

Do not pass connections outside the security context.

After a connection has been established, you must not pass it outside the security context. For example, one thread with permission to open a connection should not store the connection in a global location. If the connection is available in a global location, then another malicious thread can use the open connection without having that permission explicitly granted to it.

Be aware that logon information and passwords may be visible in a memory dump.

When data source logon and password information is supplied in the connection string, this information is maintained in memory until garbage collection reclaims the resources. This makes it impossible to determine when a password string is no longer in memory. If an application crashes, a memory dump file may contain sensitive security information, and the user running the application and any user with administrative access to the computer can view the memory dump file. Use Windows Authentication for connections to Microsoft SQL Server.

Grant users only the necessary permissions in the data source.

A data source administrator should grant only the necessary permissions to users. Even though Entity SQL does not support DML statements that modify data, such as INSERT, UPDATE, or DELETE, users can still access the connection to the data source. A malicious user could use this connection to execute DML statements in the native language of the data source.

Run applications with the minimum permissions.

When you allow a managed application to run with full-trust permission, the .NET Framework does not limit the application's access to your computer. This may enable a security vulnerability in your application to compromise the entire system. To use code access security and other security mechanisms in the .NET Framework, you should run applications by using partial-trust permissions and with the minimum set of permissions that are needed to enable the application to function. The following code access permissions are the minimum permissions your Entity Framework application needs:

For more information, see Code Access Security and ADO.NET.

Do not install untrusted applications.

The Entity Framework does not enforce any security permissions and will invoke any user-supplied data object code in process regardless of whether it is trusted or not. Ensure that authentication and authorization of the client is performed by the data store and by your application.

Restrict access to all configuration files.

An administrator must restrict write access to all files that specify configuration for an application, including to enterprisesec.config, security.config, machine.conf, and the application configuration file <application>.exe.config.

The provider invariant name is modifiable in the app.config. The client application must take responsibility for accessing the underlying provider through the standard provider factory model by using a strong name.

Restrict permissions to the model and mapping files.

An administrator must restrict write access to the model and mapping files (.edmx, .csdl, .ssdl, and .msl) to only users who modify the model or mappings. The Entity Framework only requires read access to these files at run time. An administrator should also restrict access to object layer and pre-compiled view source code files that are generated by the Entity Data Model tools.

Security Considerations for Queries

The following security considerations apply when querying a conceptual model. These considerations apply to Entity SQL queries using EntityClient and to object queries using LINQ, Entity SQL, and query builder methods.

Prevent SQL injection attacks.

Applications frequently take external input (from a user or another external agent) and perform actions based on that input. Any input that is directly or indirectly derived from the user or an external agent might have content that uses the syntax of the target language in order to perform unauthorized actions. When the target language is a Structured Query Language (SQL), such as Transact-SQL, this manipulation is known as a SQL injection attack. A malicious user can inject commands directly into the query and drop a database table, cause a denial of service, or otherwise change the nature of the operation being performed.

  • Entity SQL injection attacks:

    SQL injection attacks can be performed in Entity SQL by supplying malicious input to values that are used in a query predicate and in parameter names. To avoid the risk of SQL injection, you should never combine user input with Entity SQL command text.

    Entity SQL queries accept parameters everywhere that literals are accepted. You should use parameterized queries instead of injecting literals from an external agent directly into the query. You should also consider using query builder methods to safely construct Entity SQL.

  • LINQ to Entities injection attacks:

    Although query composition is possible in LINQ to Entities, it is performed through the object model API. Unlike Entity SQL queries, LINQ to Entities queries are not composed by using string manipulation or concatenation, and they are not susceptible to traditional SQL injection attacks.

Prevent very large result sets.

A very large result set could cause the client system to shut down if the client is performing operations that consume resources proportional to the size of the result set. Unexpectedly large result sets can occur under the following conditions:

  • In queries against a large database that do not include appropriate filter conditions.

  • In queries that create Cartesian joins on the server.

  • In nested Entity SQL queries.

When accepting user input, you must make sure that the input cannot cause result sets to become larger than what the system can handle. You can also use the Take method in LINQ to Entities or the LIMIT operator in Entity SQL to limit the size of the result set.

Avoid Returning IQueryable Results When Exposing Methods to Potentially Untrusted Callers.

Avoid returning IQueryable<T> types from methods that are exposed to potentially untrusted callers for the following reasons:

  • A consumer of a query that exposes an IQueryable<T> type could call methods on the result that expose secure data or increase the size of the result set. For example, consider the following method signature:

  • public IQueryable<Customer> GetCustomer(int customerId)  
    

    A consumer of this query could call .Include("Orders") on the returned IQueryable<Customer> to retrieve data that the query did not intend to expose. This can be avoided by changing the return type of the method to IEnumerable<T> and calling a method (such as .ToList()) that materializes the results.

  • Because IQueryable<T> queries are executed when the results are iterated over, a consumer of a query that exposes an IQueryable<T> type could catch exceptions that are thrown. Exceptions could contain information not intended for the consumer.

Security Considerations for Entities

The following security considerations apply when generating and working with entity types.

Do not share an ObjectContext across application domains.

Sharing an ObjectContext with more than one application domain may expose information in the connection string. Instead, you should transfer serialized objects or object graphs to the other application domain and then attach those objects to an ObjectContext in that application domain. For more information, see Serializing Objects.

Prevent type safety violations.

If type safety is violated, the Entity Framework cannot guarantee the integrity of data in objects. Type safety violations could occur if you allow untrusted applications to run with full-trust code access security.

Handle exceptions.

Access methods and properties of an ObjectContext within a try-catch block. Catching exceptions prevents unhandled exceptions from exposing entries in the ObjectStateManager or model information (such as table names) to users of your application.

Security Considerations for ASP.NET Applications

You should consider the following when you work with paths in ASP.NET applications.

Verify whether your host performs path checks.

When the |DataDirectory| (enclosed in pipe symbols) substitution string is used, ADO.NET verifies that the resolved path is supported. For example, ".." is not allowed behind DataDirectory. That same check for resolving the Web application root operator (~) is performed by the process hosting ASP.NET. IIS performs this check; however, hosts other than IIS may not verify that the resolved path is supported. You should know the behavior of the host on which you deploy an Entity Framework application.

Do not make assumptions about resolved path names.

Although the values to which the root operator (~) and the DataDirectory substitution string resolve should remain constant during the application's runtime, the Entity Framework does not restrict the host from modifying these values.

Verify the path length before deployment.

Before deploying an Entity Framework application, you should ensure that the values of the root operator (~) and DataDirectory substitution string do not exceed the limits of the path length in the operating system. ADO.NET data providers do not ensure that the path length is within valid limits.

Security Considerations for ADO.NET Metadata

The following security considerations apply when generating and working with model and mapping files.

Do not expose sensitive information through logging.

ADO.NET metadata service components do not log any private information. If there are results that cannot be returned because of access restrictions, database management systems and file systems should return zero results instead of raising an exception that could contain sensitive information.

Do not accept MetadataWorkspace objects from untrusted sources.

Applications should not accept instances of the MetadataWorkspace class from untrusted sources. Instead, you should explicitly construct and populate a workspace from such a source.

See also

Performance Considerations

This topic describes performance characteristics of the ADO.NET Entity Framework and provides some considerations to help improve the performance of Entity Framework applications.

Stages of Query Execution

In order to better understand the performance of queries in the Entity Framework, it is helpful to understand the operations that occur when a query executes against a conceptual model and returns data as objects. The following table describes this series of operations.

Operation Relative Cost Frequency Comments
Loading metadata Moderate Once in each application domain. Model and mapping metadata used by the Entity Framework is loaded into a MetadataWorkspace. This metadata is cached globally and is available to other instances of ObjectContext in the same application domain.
Opening the database connection Moderate1 As needed. Because an open connection to the database consumes a valuable resource, the Entity Framework opens and closes the database connection only as needed. You can also explicitly open the connection. For more information, see Managing Connections and Transactions.
Generating views High Once in each application domain. (Can be pre-generated.) Before the Entity Framework can execute a query against a conceptual model or save changes to the data source, it must generate a set of local query views to access the database. Because of the high cost of generating these views, you can pre-generate the views and add them to the project at design-time. For more information, see How to: Pre-Generate Views to Improve Query Performance.
Preparing the query Moderate2 Once for each unique query. Includes the costs to compose the query command, generate a command tree based on model and mapping metadata, and define the shape of the returned data. Because now both Entity SQL query commands and LINQ queries are cached, later executions of the same query take less time. You can still use compiled LINQ queries to reduce this cost in later executions and compiled queries can be more efficient than LINQ queries that are automatically cached. For more information, see Compiled Queries (LINQ to Entities). For general information about LINQ query execution, see LINQ to Entities. Note: LINQ to Entities queries that apply the Enumerable.Contains operator to in-memory collections are not automatically cached. Also parameterizing in-memory collections in compiled LINQ queries is not allowed.
Executing the query Low2 Once for each query. The cost of executing the command against the data source by using the ADO.NET data provider. Because most data sources cache query plans, later executions of the same query may take even less time.
Loading and validating types Low3 Once for each ObjectContext instance. Types are loaded and validated against the types that the conceptual model defines.
Tracking Low3 Once for each object that a query returns. 4 If a query uses the NoTracking merge option, this stage does not affect performance.

If the query uses the AppendOnly, PreserveChanges, or OverwriteChanges merge option, query results are tracked in the ObjectStateManager. An EntityKey is generated for each tracked object that the query returns and is used to create an ObjectStateEntry in the ObjectStateManager. If an existing ObjectStateEntry can be found for the EntityKey, the existing object is returned. If the PreserveChanges, or OverwriteChanges option is used, the object is updated before it is returned.

For more information, see Identity Resolution, State Management, and Change Tracking.
Materializing the objects Moderate3 Once for each object that a query returns. 4 The process of reading the returned DbDataReader object and creating objects and setting property values that are based on the values in each instance of the DbDataRecord class. If the object already exists in the ObjectContext and the query uses the AppendOnly or PreserveChanges merge options, this stage does not affect performance. For more information, see Identity Resolution, State Management, and Change Tracking.

1 When a data source provider implements connection pooling, the cost of opening a connection is distributed across the pool. The .NET Provider for SQL Server supports connection pooling.

2 Cost increases with increased query complexity.

3 Total cost increases proportional to the number of objects returned by the query.

4 This overhead is not required for EntityClient queries because EntityClient queries return an EntityDataReader instead of objects. For more information, see EntityClient Provider for the Entity Framework.

Additional Considerations

The following are other considerations that may affect the performance of Entity Framework applications.

Query Execution

Because queries can be resource intensive, consider at what point in your code and on what computer a query is executed.

Deferred versus immediate execution

When you create an ObjectQuery<T> or LINQ query, the query may not be executed immediately. Query execution is deferred until the results are needed, such as during a foreach (C#) or For Each (Visual Basic) enumeration or when it is assigned to fill a List<T> collection. Query execution begins immediately when you call the Execute method on an ObjectQuery<T> or when you call a LINQ method that returns a singleton query, such as First or Any. For more information, see Object Queries and Query Execution (LINQ to Entities).

Client-side execution of LINQ queries

Although the execution of a LINQ query occurs on the computer that hosts the data source, some parts of a LINQ query may be evaluated on the client computer. For more information, see the Store Execution section of Query Execution (LINQ to Entities).

Query and Mapping Complexity

The complexity of individual queries and of the mapping in the entity model will have a significant effect on query performance.

Mapping complexity

Models that are more complex than a simple one-to-one mapping between entities in the conceptual model and tables in the storage model generate more complex commands than models that have a one-to-one mapping.

Query complexity

Queries that require a large number of joins in the commands that are executed against the data source or that return a large amount of data may affect performance in the following ways:

  • Queries against a conceptual model that seem simple may result in the execution of more complex queries against the data source. This can occur because the Entity Framework translates a query against a conceptual model into an equivalent query against the data source. When a single entity set in the conceptual model maps to more than one table in the data source, or when a relationship between entities is mapped to a join table, the query command executed against the data source query may require one or more joins.

    Note

    Use the ToTraceString method of the ObjectQuery<T> or EntityCommand classes to view the commands that are executed against the data source for a given query. For more information, see How to: View the Store Commands.

  • Nested Entity SQL queries may create joins on the server and can return a large number of rows.

    The following is an example of a nested query in a projection clause:

  • SELECT c, (SELECT c, (SELECT c FROM AdventureWorksModel.Vendor AS c  ) As Inner2   
        FROM AdventureWorksModel.JobCandidate AS c  ) As Inner1   
        FROM AdventureWorksModel.EmployeeDepartmentHistory AS c  
    

    In addition, such queries cause the query pipeline to generate a single query with duplication of objects across nested queries. Because of this, a single column may be duplicated multiple times. On some databases, including SQL Server, this can cause the TempDB table to grow very large, which can decrease server performance. Care should be taken when you execute nested queries.

  • Any queries that return a large amount of data can cause decreased performance if the client is performing operations that consume resources in a way that is proportional to the size of the result set. In such cases, you should consider limiting the amount of data returned by the query. For more information, see How to: Page Through Query Results.

Any commands automatically generated by the Entity Framework may be more complex than similar commands written explicitly by a database developer. If you need explicit control over the commands executed against your data source, consider defining a mapping to a table-valued function or stored procedure.

Relationships

For optimal query performance, you must define relationships between entities both as associations in the entity model and as logical relationships in the data source.

Query Paths

By default, when you execute an ObjectQuery<T>, related objects are not returned (although objects that represent the relationships themselves are). You can load related objects in one of three ways:

  1. Set the query path before the ObjectQuery<T> is executed.

  2. Call the Load method on the navigation property that the object exposes.

  3. Set the LazyLoadingEnabled option on the ObjectContext to true. Note that this is done automatically when you generate object-layer code with the Entity Data Model Designer. For more information see Generated Code Overview.

When you consider which option to use, be aware that there is a tradeoff between the number of requests against the database and the amount of data returned in a single query. For more information, see Loading Related Objects.

Using query paths

Query paths define the graph of objects that a query returns. When you define a query path, only a single request against the database is required to return all objects that the path defines. Using query paths can result in complex commands being executed against the data source from seemingly simple object queries. This occurs because one or more joins are required to return related objects in a single query. This complexity is greater in queries against a complex entity model, such as an entity with inheritance or a path that includes many-to-many relationships.

Note

Use the ToTraceString method to see the command that will be generated by an ObjectQuery<T>. For more information, see How to: View the Store Commands.

When a query path includes too many related objects or the objects contain too much row data, the data source might be unable to complete the query. This occurs if the query requires intermediate temporary storage that exceeds the capabilities of the data source. When this occurs, you can reduce the complexity of the data source query by explicitly loading related objects.

Explicitly loading related objects

You can explicitly load related objects by calling the Load method on a navigation property that returns an EntityCollection<TEntity> or EntityReference<TEntity>. Explicitly loading objects requires a round-trip to the database every time Load is called.

Note

if you call Load while looping through a collection of returned objects, such as when you use the foreach statement (For Each in Visual Basic), the data source-specific provider must support multiple active results sets on a single connection. For a SQL Server database, you must specify a value of MultipleActiveResultSets = true in the provider connection string.

You can also use the LoadProperty method when there is no EntityCollection<TEntity> or EntityReference<TEntity> properties on entities. This is useful when you are using POCO entities.

Although explicitly loading related objects will reduce the number of joins and reduced the amount of redundant data, Load requires repeated connections to the database, which can become costly when explicitly loading a large number of objects.

Saving Changes

When you call the SaveChanges method on an ObjectContext, a separate create, update, or delete command is generated for every added, updated, or deleted object in the context. These commands are executed on the data source in a single transaction. As with queries, the performance of create, update, and delete operations depends on the complexity of the mapping in the conceptual model.

Distributed Transactions

Operations in an explicit transaction that require resources that are managed by the distributed transaction coordinator (DTC) will be much more expensive than a similar operation that does not require the DTC. Promotion to the DTC will occur in the following situations:

  • An explicit transaction with an operation against a SQL Server 2000 database or other data source that always promote explicit transactions to the DTC.

  • An explicit transaction with an operation against SQL Server 2005 when the connection is managed by the Entity Framework. This occurs because SQL Server 2005 promotes to a DTC whenever a connection is closed and reopened within a single transaction, which is the default behavior of the Entity Framework. This DTC promotion does not occur when using SQL Server 2008. To avoid this promotion when using SQL Server 2005, you must explicitly open and close the connection within the transaction. For more information, see Managing Connections and Transactions.

An explicit transaction is used when one or more operations are executed inside a System.Transactions transaction. For more information, see Managing Connections and Transactions.

Strategies for Improving Performance

You can improve the overall performance of queries in the Entity Framework by using the following strategies.

Pre-generate views

Generating views based on an entity model is a significant cost the first time that an application executes a query. Use the EdmGen.exe utility to pre-generate views as a Visual Basic or C# code file that can be added to the project during design. You could also use the Text Template Transformation Toolkit to generate pre-compiled views. Pre-generated views are validated at runtime to ensure that they are consistent with the current version of the specified entity model. For more information, see How to: Pre-Generate Views to Improve Query Performance.

When working with very large models, the following consideration applies:

The .NET metadata format limits the number of user string characters in a given binary to 16,777,215 (0xFFFFFF). If you are generating views for a very large model and the view file reaches this size limit, you will get the "No logical space left to create more user strings." compile error. This size limitation applies to all managed binaries. For more information see the blog that demonstrates how to avoid the error when working with large and complex models.

Consider using the NoTracking merge option for queries

There is a cost required to track returned objects in the object context. Detecting changes to objects and ensuring that multiple requests for the same logical entity return the same object instance requires that objects be attached to an ObjectContext instance. If you do not plan to make updates or deletes to objects and do not require identity management, consider using the NoTracking merge options when you execute queries.

Return the correct amount of data

In some scenarios, specifying a query path using the Include method is much faster because it requires fewer round trips to the database. However, in other scenarios, additional round trips to the database to load related objects may be faster because the simpler queries with fewer joins result in less redundancy of data. Because of this, we recommend that you test the performance of various ways to retrieve related objects. For more information, see Loading Related Objects.

To avoid returning too much data in a single query, consider paging the results of the query into more manageable groups. For more information, see How to: Page Through Query Results.

Limit the scope of the ObjectContext

In most cases, you should create an ObjectContext instance within a using statement (Using…End Using in Visual Basic). This can increase performance by ensuring that the resources associated with the object context are disposed automatically when the code exits the statement block. However, when controls are bound to objects managed by the object context, the ObjectContext instance should be maintained as long as the binding is needed and disposed of manually. For more information, see Managing Connections and Transactions.

Consider opening the database connection manually

When your application executes a series of object queries or frequently calls SaveChanges to persist create, update, and delete operations to the data source, the Entity Framework must continuously open and close the connection to the data source. In these situations, consider manually opening the connection at the start of these operations and either closing or disposing of the connection when the operations are complete. For more information, see Managing Connections and Transactions.

Performance Data

Some performance data for the Entity Framework is published in the following posts on the ADO.NET team blog:

See also

Deployment Considerations

This topic provides information about deploying applications that use the ADO.NET Entity Framework for data access. For more information about the Entity Framework, see Getting Started.

The Entity Framework provides a set of tools that integrate with and make it easier to develop in Visual Studio. For more information, see ADO.NET Entity Data Model Tools. This topic does not describe how to use specific technologies to deploy an Entity Framework–based application.

Visual Studio provides facilities for distributing and deploying applications, such as ClickOnce deployment. For more information, see Deploying Applications and Components in the Visual Studio documentation.

The following considerations apply when you deploy an application that uses the Entity Framework:

  • The Entity Framework is a component of the .NET Framework starting with the .NET Framework 3.5 Service Pack 1 (SP1). You must ensure that the .NET Framework 3.5 SP1 or a later version is installed when deploying an Entity Framework–based application.

  • When a conceptual model is generated by the Entity Data Model Wizard, a connection string is created in the application configuration file. Model and mapping files can be embedded as application resources or they can be copied to the output directory. By default, they are deployed as embedded application resources. Use the Metadata Artifact Processing property of the Entity Designer file to select one of these options. For more information, see How to: Copy Model and Mapping Files to the Output Directory.

  • Ensure that the model and mapping information (expressed in conceptual schema definition language (CSDL), store schema definition language (SSDL), and mapping specification language (MSL)) is deployed together with the application and in the location specified by the connection string. For more information, see Connection Strings.

  • When you embed model and mapping information as application resources, you must recompile and redeploy the application every time the conceptual model is updated.

  • Because the Entity Framework is a component of the .NET Framework, it can be redistributed with your application as permitted by the .NET Framework license agreement.

See also

Entity Framework Resources

The following external resources provide information and support for creating Entity Framework applications.

Data Developer Center
Central location for data development with Microsoft technologies.

ADO.NET Team Blog
Blog containing updates and discussion of ADO.NET features and functionality.

Entity Framework Design Blog
Design discussions and feature previews for future Entity Framework versions.

Data Platform How Do I? Videos: Entity Framework Series
Contains a set of video screen casts that demonstrate how to build applications by using various components of the Entity Framework.

Entity Framework FAQ
Wiki section containing frequently asked questions about the Entity Framework.

See also

Entity Framework Terminology

This topic defines terms frequently referenced in Entity Framework documentation. Links are provided to relevant topics where additional information is available.

Term Definition
association The definition of a relationship between entity types.

For more information, see Association Element (CSDL) and association type.
association set A logical container for instances of associations of the same type.

For more information, see AssociationSet Element (CSDL) and association set.
Code First Starting with the Entity Framework 4.1 you can create a model programmatically using Code First development. There are two different scenarios for Code First development. In both cases, the developer defines a model by coding .NET Framework class definitions, and then optionally specifies additional mapping or configuration by using Data Annotations or the fluent API.

Note, that Code First development is part of the Entity Framework 5.0. The Entity Framework 5.0 is not part of the .NET Framework, but is built on .NET Framework 4.5. The Entity Framework 5.0 is available as the ‘Entity Framework’NuGet package. For more information, see Entity Framework Releases and Versioning.
command tree A common, programmatic representation of all Entity Framework queries that are composed of one or more expressions.

For more information, see Entity Framework Overview.
complex type A .NET Framework class that represents a complex property as defined in the conceptual model. Complex types enable scalar properties to be organized within entities. Complex objects are instances of complex types. For more information, see ComplexType Element (CSDL) and complex type.
ComplexType The specification for a data type that represents a non-scalar property of an entity type that does not have a key property.

For more information, see ComplexType Element (CSDL) and complex type.
conceptual model An abstract specification for the entity types, complex types, associations, entity containers, entity sets, and association sets in the domain of an application in the Entity Framework. The conceptual model is defined in CSDL in the .csdl file.

For more information, see Modeling and Mapping.
.csdl file An XML file that contains the conceptual model, expressed in CSDL.
conceptual schema definition language (CSDL) An XML-based language that is used to define the entity types, associations, entity containers, entity sets, and association sets of a conceptual model.

For more information, see CSDL Specification.
container A logical grouping of entity and association sets.

For more information, see EntityContainer Element (CSDL) and entity container.
concurrency A process that allows multiple users to access and change shared data at the same time. By default, the Entity Framework implements an optimistic concurrency model.
direction Refers to the asymmetrical nature of some associations. Direction is specified with FromRole and ToRole attributes of a NavigationProperty or ReferentialConstraint element in a schema.

For more information, see NavigationProperty Element (CSDL) and navigation property.
eager loading The process of loading a specific set of related objects along with the objects that were explicitly requested in the query.
.edmx file An XML file that contains the conceptual model (in CSDL), the storage model (in SSDL), and the mappings between them (in MSL). The .edmx file is created by the Entity Data Model Tools. For more information, see .edmx File Overview.
end A participating entity in an association.

For more information, see End Element (CSDL) and association end.
entity A concept in the domain of an application from which a data type is defined.

For more information, see EntityType Element (CSDL) and entity type.
EntityClient A storage-independent ADO.NET data provider that contains classes such as EntityConnection, EntityCommand, and EntityDataReader. Works with Entity SQL and connects to storage specific ADO.NET data providers, such as SqlClient.

For more information, see EntityClient Provider for the Entity Framework.
entity container Specifies entity sets and association sets that will be implemented in a specified namespace.

For more information, see EntityContainer Element (CSDL) and entity container.
Entity Data Model (EDM) A set of concepts that describe the structure of data, as entities and relationships, regardless of its stored form.

For more information, see Entity Data Model.
Entity Framework A set of technologies that supports development of data-oriented software applications by enabling developers to work with conceptual models that are mapped to logical schemas in data sources.

For more information, see Entity Framework Overview.
entity set A logical container for entities of a given type and its subtypes. Entity sets are mapped to tables in a database.

For more information, see EntitySet Element (CSDL) and entity set.
Entity SQL A storage-independent dialect of SQL that works directly with conceptual entity schemas and that supports conceptual model concepts such as inheritance and relationships.

For more information, see Entity SQL Language.
entity type A .NET Framework class that represents an entity as it is defined in the conceptual model. Entity types may have scalar, complex, and navigation properties. Objects are instances of entity types. For more information, see Working with Objects.
EntityType The specification for a data type that includes a key and a named set of properties and represents a top-level item in a conceptual model or storage model.

For more information, see EntityType Element (CSDL) and entity type.
explicit loading When objects are returned by a query, related objects are not loaded at the same time. By default, they are not loaded until explicitly requested using the Load method on a navigation property.
foreign key association An association between entities that is managed through foreign key properties.
identifying relationship A relationship where the primary key of the principal entity is part of the primary key of the dependent entity. In this kind of relationship, the dependent entity cannot exist without the principal entity.
independent association An association between entities that is represented and tracked by an independent object.
key The attribute of an entity type that specifies which property or set of properties is used to identify unique instances of the entity type. Represented in the object layer by the EntityKey class.

For more information, see Key Element (CSDL) and entity key.
lazy loading When objects are returned by a query, related objects are not loaded at the same time. Instead they are loaded automatically when the navigation property is accessed.
LINQ to Entities A query syntax that defines a set of query operators that allow traversal, filter, and projection operations to be expressed in a direct, declarative way in Visual C# and Visual Basic.

For more information, see LINQ to Entities.
mapping A specification of the correspondences between items in a conceptual model and items in a storage model.

For more information, see MSL Specification.
.msl file An XML file that contains the mapping between the conceptual model and the storage model, expressed in MSL.
mapping specification language (MSL) An XML-based language that is used to map items defined in a conceptual model to items in a storage model.

For more information, see MSL Specification.
modification functions Stored procedures that are used to insert, update, and delete data that is in the data source. These functions are used in place of Entity Framework generated commands. Modification functions are defined by the Function element in the storage model. The ModificationFunctionMapping element maps these modification functions to insert, update, and delete operations against entities that are defined in the conceptual model.
multiplicity The number of entities that can exist on each side of a relationship, as defined by an association. Also known as cardinality.

For more information, see End Element (CSDL) and association end.
multiple entity sets per type The ability for an entity type to be defined in more than one entity set.

For more information, see EntitySet Element (CSDL) and How to: Define a Model with Multiple Entity Sets per Type.
navigation property A property of an entity type that represents a relationship to another entity type, as defined by an association. Navigation properties are used to return related objects as an EntityCollection<TEntity> or an EntityReference<TEntity>, depending on the multiplicity at the other end of the association.

For more information, see NavigationProperty Element (CSDL) and navigation property.
query path A string representation of a path that specifies which related objects to return when an object query is executed. A query path is defined by calling the Include method on an ObjectQuery<T>.

For more information, see Loading Related Objects.
object context Represents the entity container defined in the conceptual model. It contains a connection to the underlying data source and provides services such as change tracking and identity resolution. An object cont ext is represented by an instance of the ObjectContext or DbContext class.

DbContext is part of the Entity Framework 5.0. The Entity Framework 5.0 is not part of the .NET Framework, but is built on .NET Framework 4.5. The Entity Framework 5.0 is available as the ‘Entity Framework’NuGet package. For more information, see Entity Framework Releases and Versioning.
object layer The entity types and object context definitions that are used by the Entity Framework.
object query A query executed within an object context against a conceptual model that returns data as objects.

For more information, see Object Queries.
object-relational mapping A technique for transforming data from a relational database into data types that can be used in object-oriented software applications.

The Entity Framework provides object-relational mapping services by mapping relational data, as defined in the storage model, to data types, as defined in the conceptual model.

For more information, see Modeling and Mapping.
Object Services Services provided by the Entity Framework that enable application code to operate on entities like .NET Framework objects.
persistence-ignorant object An object that does not contain any logic that is related to data storage. Also known as a POCO entity.
POCO Plain Old CLR Object. An object that does not inherit from another class or implement an interface.
POCO entity An entity in the Entity Framework that does not inherit from EntityObject or ComplexObject and does not implement the Entity Framework interfaces. Frequently, POCO entities are existing domain objects that you use in an Entity Framework application. These entities support persistence ignorance. For more information, see Working with POCO Entities.
proxy object An object that derives from a POCO class and is generated by the Entity Framework to support change tracking and lazy loading. For more information, see Requirements for Creating POCO Proxies.
referential constraint A constraint that is defined in a conceptual model that indicates that an entity has a dependent relationship to another entity. This constraint means that an instance of a dependent entity cannot exist without a corresponding instance of the principle entity

For more information, see ReferentialConstraint Element (CSDL) and referential integrity constraint.
relationship A logical connection between entities.
role The name given to each End of an association to clarify the semantics of the relationship.

For more information, see End Element (CSDL) and association end.
scalar property A property of an entity that maps to a single field in the storage model.
self-tracking entity An entity built from a Text Template Transformation Toolkit (T4) that has the ability to record changes to scalar, complex, and navigation properties.
simple type A primitive type that is used for defining properties in the conceptual model.

For more information, see Conceptual Model Types (CSDL) and Entity Data Model: Primitive Data Types.
split entity An entity type that is mapped to two separate types in the storage model.

For more information, see How to: Define a Model with a Single Entity Mapped to Two Tables.
storage model A definition for the logical model of data in a supported data source, such as a relational database. The storage model is defined in SSDL in the .ssdl file.

For more information, see Modeling and Mapping and SSDL Specification.
.ssdl file An XML file that contains the storage model, expressed in SSDL.
store schema definition language (SSDL) An XML-based language that is used to define the entity types, associations, entity containers, entity sets, and association sets of a storage model that frequently corresponds to a database schema.

For more information, see SSDL Specification.
table-per-hierarchy A method of modeling a type hierarchy in a database that includes the attributes of all the types in the hierarchy in one table.
table-per-type A method of modeling a type hierarchy in a database that uses multiple tables with one-to-one relationships to model the various types.

See also

Getting Started

The ADO.NET Entity Framework supports data-centric applications and services, and provides a platform for programming against data that raises the level of abstraction from the logical relational level to the conceptual level. By enabling developers to work with data at a greater level of abstraction, the Entity Framework supports code that is independent of any particular data storage engine or relational schema. For more information, see Entity Framework Overview.

To quickly start using the latest version of the Entity Framework, see Get Started

See also

Getting Started with the Entity Framework

[This page is specific to the latest version of the Entity Framework. The latest version is available as the 'Entity Framework' NuGet package. For more information, see Entity Framework Releases and Versioning.]

The msdn.com/data/ef site is now the main location for the Entity Framework content.

The content for this topic is now available on the following page: Get Started.

See Also

Concepts

Entity Framework

Other Resources

Entity Framework Resources

Get started with Entity Framework 6

This guide contains a collection of links to selected documentation articles, walkthroughs and videos that can help you get started quickly.

Fundamentals

  • Get Entity Framework

    Here you will learn how to add Entity Framework to your applications and, if you want to use the EF Designer, make sure you get it installed in Visual Studio.

  • Creating a Model: Code First, the EF Designer, and the EF Workflows

    Do you prefer to specify your EF model writing code or drawing boxes and lines? Are you going to use EF to map your objects to an existing database or would you like EF to create a database tailored for your objects? Here your learn about two different approaches to use EF6: EF Designer and Code First. Make sure you follow the discussion and watch the video about the difference.

  • Working with DbContext

    DbContext is the first and most important EF type that you need to learn how to use. It serves as the launchpad for database queries and keeps track of changes you make to objects so that they can be persisted back to the database.

  • Ask a Question

    Find out how to get help from the experts and contribute your own answers to the community.

  • Contribute

    Entity Framework 6 uses an open development model. Find out how you can help make EF even better by visiting our GitHub repository.

Code First resources

EF Designer resources

Other resources

Entity SQL Language Reference

This section provides detailed documentation LINQ to Entities, Entity SQL, and the modeling and mapping languages used by the Entity Framework.

In This Section

CSDL, SSDL, and MSL Specifications

LINQ to Entities

Entity SQL Language

Canonical Functions

Related Sections

ADO.NET Entity Data Model Tools

See also

LINQ to Entities

LINQ to Entities provides Language-Integrated Query (LINQ) support that enables developers to write queries against the Entity Framework conceptual model using Visual Basic or Visual C#. Queries against the Entity Framework are represented by command tree queries, which execute against the object context. LINQ to Entities converts Language-Integrated Queries (LINQ) queries to command tree queries, executes the queries against the Entity Framework, and returns objects that can be used by both the Entity Framework and LINQ. The following is the process for creating and executing a LINQ to Entities query:

  1. Construct an ObjectQuery<T> instance from ObjectContext.

  2. Compose a LINQ to Entities query in C# or Visual Basic by using the ObjectQuery<T> instance.

  3. Convert LINQ standard query operators and expressions to command trees.

  4. Execute the query, in command tree representation, against the data source. Any exceptions thrown on the data source during execution are passed directly up to the client.

  5. Return query results back to the client.

Constructing an ObjectQuery Instance

The ObjectQuery<T> generic class represents a query that returns a collection of zero or more typed entities. An object query is typically constructed from an existing object context, instead of being manually constructed, and always belongs to that object context. This context provides the connection and metadata information that is required to compose and execute the query. The ObjectQuery<T> generic class implements the IQueryable<T> generic interface, whose builder methods enable LINQ queries to be incrementally built. You can also let the compiler infer the type of entities by using the C# var keyword (Dim in Visual Basic, with local type inference enabled).

Composing the Queries

Instances of the ObjectQuery<T> generic class, which implements the generic IQueryable<T> interface, serve as the data source for LINQ to Entities queries. In a query, you specify exactly the information that you want to retrieve from the data source. A query can also specify how that information should be sorted, grouped, and shaped before it is returned. In LINQ, a query is stored in a variable. This query variable takes no action and returns no data; it only stores the query information. After you create a query you must execute that query to retrieve any data.

LINQ to Entities queries can be composed in two different syntaxes: query expression syntax and method-based query syntax. Query expression syntax and method-based query syntax are new in C# 3.0 and Visual Basic 9.0.

For more information, see Queries in LINQ to Entities.

Query Conversion

To execute a LINQ to Entities query against the Entity Framework, the LINQ query must be converted to a command tree representation that can be executed against the Entity Framework.

LINQ to Entities queries are comprised of LINQ standard query operators (such as Select, Where, and GroupBy) and expressions (x > 10, Contact.LastName, and so on). LINQ operators are not defined by a class, but rather are methods on a class. In LINQ, expressions can contain anything allowed by types within the System.Linq.Expressions namespace and, by extension, anything that can be represented in a lambda function. This is a superset of the expressions that are allowed by the Entity Framework, which are by definition restricted to operations allowed on the database, and supported by ObjectQuery<T>.

In the Entity Framework, both operators and expressions are represented by a single type hierarchy, which are then placed in a command tree. The command tree is used by the Entity Framework to execute the query. If the LINQ query cannot be expressed as a command tree, an exception will be thrown when the query is being converted. The conversion of LINQ to Entities queries involves two sub-conversions: the conversion of the standard query operators, and the conversion of the expressions.

There are a number of LINQ standard query operators that do not have a valid translation in LINQ to Entities. Attempts to use these operators will result in an exception at query translation time. For a list of supported LINQ to Entities operators, see Supported and Unsupported LINQ Methods (LINQ to Entities).

For more information about using the standard query operators in LINQ to Entities, see Standard Query Operators in LINQ to Entities Queries.

In general, expressions in LINQ to Entities are evaluated on the server, so the behavior of the expression should not be expected to follow CLR semantics. For more information, see Expressions in LINQ to Entities Queries.

For information about how CLR method calls are mapped to canonical functions in the data source, see CLR Method to Canonical Function Mapping.

For information about how to call canonical, database, and custom functions from within LINQ to Entities queries, see Calling Functions in LINQ to Entities Queries.

Query Execution

After the LINQ query is created by the user, it is converted to a representation that is compatible with the Entity Framework (in the form of command trees), which is then executed against the data source. At query execution time, all query expressions (or components of the query) are evaluated on the client or on the server. This includes expressions that are used in result materialization or entity projections. For more information, see Query Execution. For information on how to improve performance by compiling a query once and then executing it several times with different parameters, see Compiled Queries (LINQ to Entities).

Materialization

Materialization is the process of returning query results back to the client as CLR types. In LINQ to Entities, query results data records are never returned; there is always a backing CLR type, defined by the user or by the Entity Framework, or generated by the compiler (anonymous types). All object materialization is performed by the Entity Framework. 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.

Query results are usually returned as one of the following:

  • A collection of zero or more typed entity objects or a projection of complex types defined in the conceptual model.

  • CLR types that are supported by the Entity Framework.

  • Inline collections.

  • Anonymous types.

For more information, see Query Results.

In This Section

Queries in LINQ to Entities

Expressions in LINQ to Entities Queries

Calling Functions in LINQ to Entities Queries

Compiled Queries (LINQ to Entities)

Query Execution

Query Results

Standard Query Operators in LINQ to Entities Queries

CLR Method to Canonical Function Mapping

Supported and Unsupported LINQ Methods (LINQ to Entities)

Known Issues and Considerations in LINQ to Entities

See also

Queries in LINQ to Entities

A query is an expression that retrieves data from a data source. Queries are usually expressed in a specialized query language, such as SQL for relational databases and XQuery for XML. Therefore, developers have had to learn a new query language for each type of data source or data format that they query. Language-Integrated Query (LINQ) offers a simpler, consistent model for working with data across various kinds of data sources and formats. In a LINQ query, you always work with programming objects.

A LINQ query operation consists of three actions: obtain the data source or sources, create the query, and execute the query.

Data sources that implement the IEnumerable<T> generic interface or the IQueryable<T> generic interface can be queried through LINQ. Instances of the generic ObjectQuery<T> class, which implements the generic IQueryable<T> interface, serve as the data source for LINQ to Entities queries. The ObjectQuery<T> generic class represents a query that returns a collection of zero or more typed objects. You can also let the compiler infer the type of an entity by using the C# keyword var (Dim in Visual Basic).

In the query, you specify exactly the information that you want to retrieve from the data source. A query can also specify how that information should be sorted, grouped, and shaped before it is returned. In LINQ, a query is stored in a variable. If the query returns a sequence of values, the query variable itself must be a queryable type. This query variable takes no action and returns no data; it only stores the query information. After you create a query you must execute that query to retrieve any data.

Query Syntax

LINQ to Entities queries can be composed in two different syntaxes: query expression syntax and method-based query syntax. Query expression syntax is new in C# 3.0 and Visual Basic 9.0, and it consists of a set of clauses written in a declarative syntax similar to Transact-SQL or XQuery. However, the .NET Framework common language runtime (CLR) cannot read the query expression syntax itself. Therefore, at compile time, query expressions are translated to something that the CLR does understand: method calls. These methods are known as the standard query operators. As a developer, you have the option of calling them directly by using method syntax, instead of using query syntax. For more information, see Query Syntax and Method Syntax in LINQ.

Query Expression Syntax

Query expressions are a declarative query syntax. This syntax enables a developer to write queries in a high-level language that is formatted similar to Transact-SQL. By using query expression syntax, you can perform even complex filtering, ordering, and grouping operations on data sources with minimal code. For more information, Basic Query Operations (Visual Basic). For examples that demonstrate how to use the query expression syntax, see the following topics:

Method-Based Query Syntax

Another way to compose LINQ to Entities queries is by using method-based queries. The method-based query syntax is a sequence of direct method calls to LINQ operator methods, passing lambda expressions as the parameters. For more information, see Lambda Expressions. For examples that demonstrate how to use method-based syntax, see the following topics:

See also

Method-Based Query Syntax Examples: Projection

The examples in this topic demonstrate how to use the Select and SelectMany methods to query the AdventureWorks Sales Model using method-based query syntax. The AdventureWorks Sales Model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

Select

Example

The following example uses the Select method to project the Product.Name and Product.ProductID properties into a sequence of anonymous types.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var query = context.Products
        .Select(product => new
        {
            ProductId = product.ProductID,
            ProductName = product.Name
        });

    Console.WriteLine("Product Info:");
    foreach (var productInfo in query)
    {
        Console.WriteLine("Product Id: {0} Product name: {1} ",
            productInfo.ProductId, productInfo.ProductName);
    }
}

Example

The following example uses the Select method to return a sequence of only product names.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<string> productNames = context.Products
        .Select(p => p.Name);

    Console.WriteLine("Product Names:");
    foreach (String productName in productNames)
    {
        Console.WriteLine(productName);
    }
}

SelectMany

Example

The following example uses the SelectMany method to select all orders where TotalDue is less than 500.00.

C#
decimal totalDue = 500.00M;
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
    contacts.SelectMany(
        contact => orders.Where(order =>
            (contact.ContactID == order.Contact.ContactID)
                && order.TotalDue < totalDue)
            .Select(order => new
            {
                ContactID = contact.ContactID,
                LastName = contact.LastName,
                FirstName = contact.FirstName,
                OrderID = order.SalesOrderID,
                Total = order.TotalDue
            }));

    foreach (var smallOrder in query)
    {
        Console.WriteLine("Contact ID: {0} Name: {1}, {2} Order ID: {3} Total Due: ${4} ",
            smallOrder.ContactID, smallOrder.LastName, smallOrder.FirstName,
            smallOrder.OrderID, smallOrder.Total);
    }
}

Example

The following example uses the SelectMany method to select all orders where the order was made on October 1, 2002 or later.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
    contacts.SelectMany(
        contact => orders.Where(order =>
            (contact.ContactID == order.Contact.ContactID)
                && order.OrderDate >= new DateTime(2002, 10, 1))
            .Select(order => new
            {
                ContactID = contact.ContactID,
                LastName = contact.LastName,
                FirstName = contact.FirstName,
                OrderID = order.SalesOrderID,
                OrderDate = order.OrderDate
            }));

    foreach (var order in query)
    {
        Console.WriteLine("Contact ID: {0} Name: {1}, {2} Order ID: {3} Order date: {4:d} ",
            order.ContactID, order.LastName, order.FirstName,
            order.OrderID, order.OrderDate);
    }
}

See also

Method-Based Query Syntax Examples: Filtering

The examples in this topic demonstrate how to use the Where and Where…Contains methods to query the AdventureWorks Sales Model using method-based query syntax. Note, Where…Contains cannot be used as a part of a compiled query.

The AdventureWorks Sales model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

Where

Example

The following example returns all online orders.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var onlineOrders = context.SalesOrderHeaders
        .Where(order => order.OnlineOrderFlag == true)
        .Select(s => new { s.SalesOrderID, s.OrderDate, s.SalesOrderNumber });

    foreach (var onlineOrder in onlineOrders)
    {
        Console.WriteLine("Order ID: {0} Order date: {1:d} Order number: {2}",
            onlineOrder.SalesOrderID,
            onlineOrder.OrderDate,
            onlineOrder.SalesOrderNumber);
    }
}

Example

The following example returns the orders where the order quantity is greater than 2 and less than 6.

C#
int orderQtyMin = 2;
int orderQtyMax = 6;
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var query = context.SalesOrderDetails
        .Where(order => order.OrderQty > orderQtyMin && order.OrderQty < orderQtyMax)
        .Select(s => new { s.SalesOrderID, s.OrderQty });

    foreach (var order in query)
    {
        Console.WriteLine("Order ID: {0} Order quantity: {1}",
            order.SalesOrderID, order.OrderQty);
    }
}

Example

The following example returns all red colored products.

C#
String color = "Red";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var query = context.Products
        .Where(product => product.Color == color)
        .Select(p => new { p.Name, p.ProductNumber, p.ListPrice });

    foreach (var product in query)
    {
        Console.WriteLine("Name: {0}", product.Name);
        Console.WriteLine("Product number: {0}", product.ProductNumber);
        Console.WriteLine("List price: ${0}", product.ListPrice);
        Console.WriteLine("");
    }
}

Example

The following example uses the Where method to find orders that were made after December 1, 2003 and then uses the order.SalesOrderDetail navigation property to get the details for each order.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<SalesOrderHeader> query = context.SalesOrderHeaders
        .Where(order => order.OrderDate >= new DateTime(2003, 12, 1));

    Console.WriteLine("Orders that were made after December 1, 2003:");
    foreach (SalesOrderHeader order in query)
    {
        Console.WriteLine("OrderID {0} Order date: {1:d} ",
            order.SalesOrderID, order.OrderDate);
        foreach (SalesOrderDetail orderDetail in order.SalesOrderDetails)
        {
            Console.WriteLine("  Product ID: {0} Unit Price {1}",
                orderDetail.ProductID, orderDetail.UnitPrice);
        }
    }
}

Where…Contains

Example

The following example uses an array as part of a Where…Contains clause to find all products that have a ProductModelID that matches a value in the array.

C#
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    int?[] productModelIds = { 19, 26, 118 };
    var products = AWEntities.Products.
        Where(p => productModelIds.Contains(p.ProductModelID));
   
    foreach (var product in products)
    {
        Console.WriteLine("{0}: {1}", product.ProductModelID, product.ProductID);
    }
}

Note

As part of the predicate in a Where…Contains clause, you can use an Array, a List<T>, or a collection of any type that implements the IEnumerable<T> interface. You can also declare and initialize a collection within a LINQ to Entities query. See the next example for more information.

Example

The following example declares and initializes arrays in a Where…Contains clause to find all products that have a ProductModelID or a Size that matches a value in the arrays.

C#
  using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
  {
      var products = AWEntities.Products.
          Where(p => (new int?[] { 19, 26, 18 }).Contains(p.ProductModelID) || 
                     (new string[] { "L", "XL" }).Contains(p.Size));

      foreach (var product in products)
      {
          Console.WriteLine("{0}: {1}, {2}", product.ProductID, 
                                             product.ProductModelID, 
                                             product.Size);
      }
  }

See also

Method-Based Query Syntax Examples: Ordering

The examples in this topic demonstrate how to use the ThenBy method to query the AdventureWorks Sales Model using method-based query syntax. The AdventureWorks Sales Model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

ThenBy

Example

The following example in method-based query syntax uses OrderBy and ThenBy to return a list of contacts ordered by last name and then by first name.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<Contact> sortedContacts = context.Contacts
        .OrderBy(c => c.LastName)
        .ThenBy(c => c.FirstName);

    Console.WriteLine("The list of contacts sorted by last name then by first name:");
    foreach (Contact sortedContact in sortedContacts)
    {
        Console.WriteLine(sortedContact.LastName + ", " + sortedContact.FirstName);
    }
}

ThenByDescending

Example

The following example uses the OrderBy and ThenByDescending methods to first sort by list price, and then perform a descending sort of the product names.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IOrderedQueryable<Product> query = context.Products
        .OrderBy(product => product.ListPrice)
        .ThenByDescending(product => product.Name);

    foreach (Product product in query)
    {
        Console.WriteLine("Product ID: {0} Product Name: {1} List Price {2}",
            product.ProductID,
            product.Name,
            product.ListPrice);
    }
}

See also

Method-Based Query Syntax Examples: Aggregate Operators

The examples in this topic demonstrate how to use the Aggregate, Average, Count, LongCount, Max, Min, and Sum methods to query the AdventureWorks Sales Model using method-based query syntax. The AdventureWorks Sales Model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

Average

Example

The following example uses the Average method to find the average list price of the products.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Product> products = context.Products;

    Decimal averageListPrice =
        products.Average(product => product.ListPrice);

    Console.WriteLine("The average list price of all the products is ${0}",
        averageListPrice);
}

Example

The following example uses the Average method to find the average list price of the products of each style.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Product> products = context.Products;

    var query = from product in products
                group product by product.Style into g
                select new
                {
                    Style = g.Key,
                    AverageListPrice =
                        g.Average(product => product.ListPrice)
                };

    foreach (var product in query)
    {
        Console.WriteLine("Product style: {0} Average list price: {1}",
            product.Style, product.AverageListPrice);
    }
}

Example

The following example uses the Average method to find the average total due.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    Decimal averageTotalDue = orders.Average(order => order.TotalDue);
    Console.WriteLine("The average TotalDue is {0}.", averageTotalDue);
}

Example

The following example uses the Average method to get the average total due for each contact ID.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from order in orders
        group order by order.Contact.ContactID into g
        select new
        {
            Category = g.Key,
            averageTotalDue = g.Average(order => order.TotalDue)
        };

    foreach (var order in query)
    {
        Console.WriteLine("ContactID = {0} \t Average TotalDue = {1}",
            order.Category, order.averageTotalDue);
    }
}

Example

The following example uses the Average method to get the orders with the average total due for each contact.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from order in orders
        group order by order.Contact.ContactID into g
        let averageTotalDue = g.Average(order => order.TotalDue)
        select new
        {
            Category = g.Key,
            CheapestProducts =
                g.Where(order => order.TotalDue == averageTotalDue)
        };

    foreach (var orderGroup in query)
    {
        Console.WriteLine("ContactID: {0}", orderGroup.Category);
        foreach (var order in orderGroup.CheapestProducts)
        {
            Console.WriteLine("Average total due for SalesOrderID {1} is: {0}",
                order.TotalDue, order.SalesOrderID);
        }
        Console.Write("\n");
    }
}

Count

Example

The following example uses the Count method to return the number of products in the Product table.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Product> products = context.Products;

    int numProducts = products.Count();

    Console.WriteLine("There are {0} products.", numProducts);
}

Example

The following example uses the Count method to return a list of contact IDs and how many orders each has.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;

    //Can't find field SalesOrderContact
    var query =
        from contact in contacts
        select new
        {
            CustomerID = contact.ContactID,
            OrderCount = contact.SalesOrderHeaders.Count()
        };

    foreach (var contact in query)
    {
        Console.WriteLine("CustomerID = {0} \t OrderCount = {1}",
            contact.CustomerID,
            contact.OrderCount);
    }
}

Example

The following example groups products by color and uses the Count method to return the number of products in each color group.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Product> products = context.Products;

    var query =
        from product in products
        group product by product.Color into g
        select new { Color = g.Key, ProductCount = g.Count() };

    foreach (var product in query)
    {
        Console.WriteLine("Color = {0} \t ProductCount = {1}",
            product.Color,
            product.ProductCount);
    }
}

LongCount

Example

The following example gets the contact count as a long integer.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;

    long numberOfContacts = contacts.LongCount();
    Console.WriteLine("There are {0} Contacts", numberOfContacts);
}

Max

Example

The following example uses the Max method to get the largest total due.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    Decimal maxTotalDue = orders.Max(w => w.TotalDue);
    Console.WriteLine("The maximum TotalDue is {0}.",
        maxTotalDue);
}

Example

The following example uses the Max method to get the largest total due for each contact ID.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from order in orders
        group order by order.Contact.ContactID into g
        select new
        {
            Category = g.Key,
            maxTotalDue =
                g.Max(order => order.TotalDue)
        };

    foreach (var order in query)
    {
        Console.WriteLine("ContactID = {0} \t Maximum TotalDue = {1}",
            order.Category, order.maxTotalDue);
    }
}

Example

The following example uses the Max method to get the orders with the largest total due for each contact ID.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from order in orders
        group order by order.Contact.ContactID into g
        let maxTotalDue = g.Max(order => order.TotalDue)
        select new
        {
            Category = g.Key,
            CheapestProducts =
                g.Where(order => order.TotalDue == maxTotalDue)
        };

    foreach (var orderGroup in query)
    {
        Console.WriteLine("ContactID: {0}", orderGroup.Category);
        foreach (var order in orderGroup.CheapestProducts)
        {
            Console.WriteLine("MaxTotalDue {0} for SalesOrderID {1}: ",
                order.TotalDue,
                order.SalesOrderID);
        }
        Console.Write("\n");
    }
}

Min

Example

The following example uses the Min method to get the smallest total due.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    Decimal smallestTotalDue = orders.Min(totalDue => totalDue.TotalDue);
    Console.WriteLine("The smallest TotalDue is {0}.",
        smallestTotalDue);
}

Example

The following example uses the Min method to get the smallest total due for each contact ID.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from order in orders
        group order by order.Contact.ContactID into g
        select new
        {
            Category = g.Key,
            smallestTotalDue =
                g.Min(order => order.TotalDue)
        };

    foreach (var order in query)
    {
        Console.WriteLine("ContactID = {0} \t Minimum TotalDue = {1}",
            order.Category, order.smallestTotalDue);
    }
}

Example

The following example uses the Min method to get the orders with the smallest total due for each contact.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from order in orders
        group order by order.Contact.ContactID into g
        let minTotalDue = g.Min(order => order.TotalDue)
        select new
        {
            Category = g.Key,
            smallestTotalDue =
                g.Where(order => order.TotalDue == minTotalDue)
        };


    foreach (var orderGroup in query)
    {
        Console.WriteLine("ContactID: {0}", orderGroup.Category);
        foreach (var order in orderGroup.smallestTotalDue)
        {
            Console.WriteLine("Mininum TotalDue {0} for SalesOrderID {1}: ",
                order.TotalDue,
                order.SalesOrderID);
        }
        Console.Write("\n");
    }
}

Sum

Example

The following example uses the Sum method to get the total number of order quantities in the SalesOrderDetail table.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderDetail> orders = context.SalesOrderDetails;

    double totalOrderQty = orders.Sum(o => o.OrderQty);
    Console.WriteLine("There are a total of {0} OrderQty.",
        totalOrderQty);
}

Example

The following example uses the Sum method to get the total due for each contact ID.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from order in orders
        group order by order.Contact.ContactID into g
        select new
        {
            Category = g.Key,
            TotalDue = g.Sum(order => order.TotalDue)
        };

    foreach (var order in query)
    {
        Console.WriteLine("ContactID = {0} \t TotalDue sum = {1}",
            order.Category, order.TotalDue);
    }
}

See also

Method-Based Query Syntax Examples: Partitioning

The examples in this topic demonstrate how to use the Skip, and Take methods to query the AdventureWorks Sales Model using query expression syntax. The AdventureWorks Sales Model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

Skip

Example

The following example uses the Skip method to get all but the first five contacts of the Contact table.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    // LINQ to Entities only supports Skip on ordered collections.
    IOrderedQueryable<Product> products = context.Products
            .OrderBy(p => p.ListPrice);

    IQueryable<Product> allButFirst3Products = products.Skip(3);

    Console.WriteLine("All but first 3 products:");
    foreach (Product product in allButFirst3Products)
    {
        Console.WriteLine("Name: {0} \t ID: {1}",
            product.Name,
            product.ProductID);
    }
}

Example

The following example uses the Skip method to get all but the first two addresses in Seattle.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Address> addresses = context.Addresses;
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    //LINQ to Entities only supports Skip on ordered collections.
    var query = (
        from address in addresses
        from order in orders
        where address.AddressID == order.Address.AddressID
             && address.City == "Seattle"
        orderby order.SalesOrderID
        select new
        {
            City = address.City,
            OrderID = order.SalesOrderID,
            OrderDate = order.OrderDate
        }).Skip(2);

    Console.WriteLine("All but first 2 orders in Seattle:");
    foreach (var order in query)
    {
        Console.WriteLine("City: {0} Order ID: {1} Total Due: {2:d}",
            order.City, order.OrderID, order.OrderDate);
    }

Take

Example

The following example uses the Take method to get only the first five contacts from the Contact table.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<Contact> first5Contacts = context.Contacts.Take(5);

    Console.WriteLine("First 5 contacts:");
    foreach (Contact contact in first5Contacts)
    {
        Console.WriteLine("Title = {0} \t FirstName = {1} \t Lastname = {2}",
            contact.Title,
            contact.FirstName,
            contact.LastName);
    }
}

Example

The following example uses the Take method to get the first three addresses in Seattle.

C#
String city = "Seattle";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Address> addresses = context.Addresses;
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query = (
        from address in addresses
        from order in orders
        where address.AddressID == order.Address.AddressID
             && address.City == city
        select new
        {
            City = address.City,
            OrderID = order.SalesOrderID,
            OrderDate = order.OrderDate
        }).Take(3);
    Console.WriteLine("First 3 orders in Seattle:");
    foreach (var order in query)
    {
        Console.WriteLine("City: {0} Order ID: {1} Total Due: {2:d}",
            order.City, order.OrderID, order.OrderDate);
    }
}

See also

Method-Based Query Syntax Examples: Conversion

The examples in this topic demonstrate how to use the ToArray, ToDictionary and ToList methods to query the AdventureWorks Sales Model using method-based query syntax. The AdventureWorks Sales Model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

ToArray

Example

The following example uses the ToArray method to immediately evaluate a sequence into an array.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Product> products = context.Products;

    Product[] prodArray = (
        from product in products
        orderby product.ListPrice descending
        select product).ToArray();

    Console.WriteLine("Every price from highest to lowest:");
    foreach (Product product in prodArray)
    {
        Console.WriteLine(product.ListPrice);
    }
}

ToDictionary

Example

The following example uses the ToDictionary method to immediately evaluate a sequence and a related key expression into a dictionary.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Product> products = context.Products;

    Dictionary<String, Product> scoreRecordsDict = products.
            ToDictionary(record => record.Name);

    Console.WriteLine("Top Tube's ProductID: {0}",
            scoreRecordsDict["Top Tube"].ProductID);
}

ToList

Example

The following example uses the ToList method to immediately evaluate a sequence into a List<T>, where T is of type DataRow.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Product> products = context.Products;

    List<Product> query =
        (from product in products
         orderby product.Name
         select product).ToList();

    Console.WriteLine("The product list, ordered by product name:");
    foreach (Product product in query)
    {
        Console.WriteLine(product.Name.ToLower(CultureInfo.InvariantCulture));
    }
}

See also

Method-Based Query Syntax Examples: Join Operators

The examples in this topic demonstrate how to use the Join and GroupJoin methods to query the AdventureWorks Sales Model using method-based query syntax. The AdventureWorks Sales Model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

GroupJoin

Example

The following example performs a GroupJoin over the SalesOrderHeader and SalesOrderDetail tables to find the number of orders per customer. A group join is the equivalent of a left outer join, which returns each element of the first (left) data source, even if no correlated elements are in the other data source.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;
    ObjectSet<SalesOrderDetail> details = context.SalesOrderDetails;

    var query = orders.GroupJoin(details, 
        order => order.SalesOrderID,
        detail => detail.SalesOrderID,
        (order, orderGroup) => new
        {
            CustomerID = order.SalesOrderID,
            OrderCount = orderGroup.Count()
        });

    foreach (var order in query)
    {
        Console.WriteLine("CustomerID: {0}  Orders Count: {1}",
            order.CustomerID,
            order.OrderCount);
    }

}

Example

The following example performs a GroupJoin over the Contact and SalesOrderHeader tables to find the number of orders per contact. The order count and IDs for each contact are displayed.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query = contacts.GroupJoin(orders, 
        contact => contact.ContactID,
        order => order.Contact.ContactID,
        (contact, contactGroup) => new
        {
            ContactID = contact.ContactID,
            OrderCount = contactGroup.Count(),
            Orders = contactGroup
        });

    foreach (var group in query)
    {
        Console.WriteLine("ContactID: {0}", group.ContactID);
        Console.WriteLine("Order count: {0}", group.OrderCount);
        foreach (var orderInfo in group.Orders)
        {
            Console.WriteLine("   Sale ID: {0}", orderInfo.SalesOrderID);
        }
        Console.WriteLine("");
    }
    }

Join

Example

The following example performs a join over the Contact and SalesOrderHeader tables.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        contacts.Join(
            orders,
            order => order.ContactID,
            contact => contact.Contact.ContactID,
            (contact, order) => new
            {
                ContactID = contact.ContactID,
                SalesOrderID = order.SalesOrderID,
                FirstName = contact.FirstName,
                Lastname = contact.LastName,
                TotalDue = order.TotalDue
            });

    foreach (var contact_order in query)
    {
        Console.WriteLine("ContactID: {0} "
                        + "SalesOrderID: {1} "
                        + "FirstName: {2} "
                        + "Lastname: {3} "
                        + "TotalDue: {4}",
            contact_order.ContactID,
            contact_order.SalesOrderID,
            contact_order.FirstName,
            contact_order.Lastname,
            contact_order.TotalDue);
    }
}

Example

The following example performs a join over the Contact and SalesOrderHeader tables, grouping the results by contact ID.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query = contacts.Join(
        orders,
        order => order.ContactID,
        contact => contact.Contact.ContactID,
        (contact, order) => new
        {
            ContactID = contact.ContactID,
            SalesOrderID = order.SalesOrderID,
            FirstName = contact.FirstName,
            Lastname = contact.LastName,
            TotalDue = order.TotalDue
        })
            .GroupBy(record => record.ContactID);

    foreach (var group in query)
    {
        foreach (var contact_order in group)
        {
            Console.WriteLine("ContactID: {0} "
                            + "SalesOrderID: {1} "
                            + "FirstName: {2} "
                            + "Lastname: {3} "
                            + "TotalDue: {4}",
                contact_order.ContactID,
                contact_order.SalesOrderID,
                contact_order.FirstName,
                contact_order.Lastname,
                contact_order.TotalDue);
        }
    }
}

See also

Method-Based Query Syntax Examples: Element Operators

The examples in this topic demonstrate how to use the First method to query the AdventureWorks Sales Model using method-based query syntax. The AdventureWorks Sales Model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The example in this topic uses the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

First

Example

The following example uses the First method to find the first email address that starts with 'caroline'.

C#
string name = "caroline";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;

    Contact query = contacts.First(contact =>
        contact.EmailAddress.StartsWith(name));

    Console.WriteLine("An email address starting with 'caroline': {0}",
        query.EmailAddress);
}

See also

Method-Based Query Syntax Examples: Grouping

The examples in this topic show you how to use the GroupBy method to query the AdventureWorks Sales Model using method-based query syntax. The AdventureWorks Sales Model that is used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

Example

The following example uses the GroupBy method to return Address objects that are grouped by postal code. The results are projected into an anonymous type.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var query = context.Addresses
        .GroupBy( address => address.PostalCode);                     
        
    foreach (IGrouping<string, Address> addressGroup in query)
    {
        Console.WriteLine("Postal Code: {0}", addressGroup.Key);
        foreach (Address address in addressGroup)
        {
            Console.WriteLine("\t" + address.AddressLine1 +
                address.AddressLine2);
        }
    }
}

Example

The following example uses the GroupBy method to return Contact objects that are grouped by the first letter of the contact's last name. The results are also sorted by the first letter of the last name and projected into an anonymous type.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var query = context.Contacts
        .GroupBy(c => c.LastName.Substring(0,1))
        .OrderBy(c => c.Key);

    foreach (IGrouping<string, Contact> group in query)
    {
        Console.WriteLine("Last names that start with the letter '{0}':",
            group.Key);
        foreach (Contact contact in group)
        {
            Console.WriteLine(contact.LastName);
        }
        
    }
}

Example

The following example uses the GroupBy method to return SalesOrderHeader objects that are grouped by customer ID. The number of sales for each customer is also returned.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var query = context.SalesOrderHeaders
        .GroupBy(order => order.CustomerID);
        
    foreach (IGrouping<int, SalesOrderHeader> group in query)
    {
        Console.WriteLine("Customer ID: {0}", group.Key);
        Console.WriteLine("Order count: {0}", group.Count());

        foreach (SalesOrderHeader sale in group)
        {
            Console.WriteLine("   Sale ID: {0}", sale.SalesOrderID);
        }
        Console.WriteLine("");                    
    }
}

See also

Method-Based Query Syntax Examples: Navigating Relationships

Navigation properties in the Entity Framework are shortcut properties used to locate the entities at the ends of an association. Navigation properties allow a user to navigate from one entity to another, or from one entity to related entities through an association set. This topic provides examples in method-based query syntax of how to navigate relationships through navigation properties in LINQ to Entities queries.

The AdventureWorks Sales Model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

Example

The following example in method-based query syntax uses the SelectMany method to get all the orders of the contacts whose last name is "Zhou". The Contact.SalesOrderHeader navigation property is used to get the collection of SalesOrderHeader objects for each contact.

C#
string lastName = "Zhou";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<SalesOrderHeader> ordersQuery = context.Contacts
        .Where(c => c.LastName == lastName)
        .SelectMany(c => c.SalesOrderHeaders);

    foreach (var order in ordersQuery)
    {
        Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}",
            order.SalesOrderID, order.OrderDate, order.TotalDue);
    }
}

Example

The following example in method-based query syntax uses the Select method to get all the contact IDs and the sum of the total due for each contact whose last name is "Zhou". The Contact.SalesOrderHeader navigation property is used to get the collection of SalesOrderHeader objects for each contact. The Sum method uses the Contact.SalesOrderHeader navigation property to sum the total due of all the orders for each contact.

C#
string lastName = "Zhou";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var ordersQuery = context.Contacts
        .Where(c => c.LastName == lastName)
        .Select(c => new
        {
            ContactID = c.ContactID,
            Total = c.SalesOrderHeaders.Sum(o => o.TotalDue)
        });

    foreach (var contact in ordersQuery)
    {
        Console.WriteLine("Contact ID: {0} Orders total: {1}", contact.ContactID, contact.Total);
    }
}

Example

The following example in method-based query syntax gets all the orders of the contacts whose last name is "Zhou". The Contact.SalesOrderHeader navigation property is used to get the collection of SalesOrderHeader objects for each contact. The contact's name and orders are returned in an anonymous type.

C#
string lastName = "Zhou";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var ordersQuery = context.Contacts
        .Where(c => c.LastName == lastName)
        .Select(c => new { LastName = c.LastName, Orders = c.SalesOrderHeaders });

    foreach (var order in ordersQuery)
    {
        Console.WriteLine("Name: {0}", order.LastName);
        foreach (SalesOrderHeader orderInfo in order.Orders)
        {
            Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}",
                orderInfo.SalesOrderID, orderInfo.OrderDate, orderInfo.TotalDue);
        }
        Console.WriteLine("");
    }
}

Example

The following example uses the SalesOrderHeader.Address and SalesOrderHeader.Contact navigation properties to get the collection of Address and Contact objects associated with each order. The last name of the contact, the street address, the sales order number, and the total due for each order to the city of Seattle are returned in an anonymous type.

C#
string city = "Seattle";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var ordersQuery = context.SalesOrderHeaders
        .Where(o => o.Address.City == city)
        .Select(o => new
        {
            ContactLastName = o.Contact.LastName,
            ContactFirstName = o.Contact.FirstName,
            StreetAddress = o.Address.AddressLine1,
            OrderNumber = o.SalesOrderNumber,
            TotalDue = o.TotalDue
        });

    foreach (var orderInfo in ordersQuery)
    {
        Console.WriteLine("Name: {0}, {1}", orderInfo.ContactLastName, orderInfo.ContactFirstName);
        Console.WriteLine("Street address: {0}", orderInfo.StreetAddress);
        Console.WriteLine("Order number: {0}", orderInfo.OrderNumber);
        Console.WriteLine("Total Due: {0}", orderInfo.TotalDue);
        Console.WriteLine("");
    }
}

Example

The following example uses the Where method to find orders that were made after December 1, 2003, and then uses the order.SalesOrderDetail navigation property to get the details for each order.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<SalesOrderHeader> query =
        from order in context.SalesOrderHeaders
        where order.OrderDate >= new DateTime(2003, 12, 1)
        select order;


    Console.WriteLine("Orders that were made after December 1, 2003:");
    foreach (SalesOrderHeader order in query)
    {
        Console.WriteLine("OrderID {0} Order date: {1:d} ",
            order.SalesOrderID, order.OrderDate);
        foreach (SalesOrderDetail orderDetail in order.SalesOrderDetails)
        {
            Console.WriteLine("  Product ID: {0} Unit Price {1}",
                orderDetail.ProductID, orderDetail.UnitPrice);
        }
    }
}

See also

Query Expression Syntax Examples: Projection

The examples in this topic demonstrate how to use the Select method and the From … From … keywords to query the AdventureWorks Sales Model using query expression syntax. From … From … is the query based equivalent of the SelectMany method. The AdventureWorks Sales model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

Select

Example

The following example uses the Select method to return all the rows from the Product table and display the product names.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<Product> productsQuery = from product in context.Products
                                        select product;

    Console.WriteLine("Product Names:");
    foreach (var prod in productsQuery)
    {
        Console.WriteLine(prod.Name);
    }
}

Example

The following example uses Select to return a sequence of only product names.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<string> productNames =
        from p in context.Products
        select p.Name;

    Console.WriteLine("Product Names:");
    foreach (String productName in productNames)
    {
        Console.WriteLine(productName);
    }
}

Example

The following example uses the Select method to project the Product.Name and Product.ProductID properties into a sequence of anonymous types.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var query =
        from product in context.Products
        select new
        {
            ProductId = product.ProductID,
            ProductName = product.Name
        };

    Console.WriteLine("Product Info:");
    foreach (var productInfo in query)
    {
        Console.WriteLine("Product Id: {0} Product name: {1} ",
            productInfo.ProductId, productInfo.ProductName);
    }
}

From … From … (SelectMany)

Example

The following example uses From … From … (the equivalent of the SelectMany method) to select all orders where TotalDue is less than 500.00.

C#
decimal totalDue = 500.00M;
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from contact in contacts
        from order in orders
        where contact.ContactID == order.Contact.ContactID
            && order.TotalDue < totalDue
        select new
        {
            ContactID = contact.ContactID,
            LastName = contact.LastName,
            FirstName = contact.FirstName,
            OrderID = order.SalesOrderID,
            Total = order.TotalDue
        };

    foreach (var smallOrder in query)
    {
        Console.WriteLine("Contact ID: {0} Name: {1}, {2} Order ID: {3} Total Due: ${4} ",
            smallOrder.ContactID, smallOrder.LastName, smallOrder.FirstName,
            smallOrder.OrderID, smallOrder.Total);
    }
}

Example

The following example uses From … From … (the equivalent of the SelectMany method) to select all orders where the order was made on October 1, 2002 or later.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from contact in contacts
        from order in orders
        where contact.ContactID == order.Contact.ContactID
            && order.OrderDate >= new DateTime(2002, 10, 1)
        select new
        {
            ContactID = contact.ContactID,
            LastName = contact.LastName,
            FirstName = contact.FirstName,
            OrderID = order.SalesOrderID,
            OrderDate = order.OrderDate
        };

    foreach (var order in query)
    {
        Console.WriteLine("Contact ID: {0} Name: {1}, {2} Order ID: {3} Order date: {4:d} ",
            order.ContactID, order.LastName, order.FirstName,
            order.OrderID, order.OrderDate);
    }
}

Example

The following example uses a From … From … (the equivalent of the SelectMany method) to select all orders where the order total is greater than 10000.00 and uses From assignment to avoid requesting the total twice.

C#
decimal totalDue = 10000.0M;
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from contact in contacts
        from order in orders
        let total = order.TotalDue
        where contact.ContactID == order.Contact.ContactID
            && total >= totalDue
        select new
        {
            ContactID = contact.ContactID,
            LastName = contact.LastName,
            OrderID = order.SalesOrderID,
            total
        };

    foreach (var order in query)
    {
        Console.WriteLine("Contact ID: {0} Last name: {1} Order ID: {2} Total: {3}",
            order.ContactID, order.LastName, order.OrderID, order.total);
    }
}

See also

Query Expression Syntax Examples: Filtering

The examples in this topic demonstrate how to use the Where and Where…Contains methods to query the AdventureWorks Sales Model using query expression syntax. Note, Where…Contains cannot be used as a part of a compiled query.

The AdventureWorks Sales model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

Where

Example

The following example returns all online orders.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var onlineOrders =
        from order in context.SalesOrderHeaders
        where order.OnlineOrderFlag == true
        select new
        {
            SalesOrderID = order.SalesOrderID,
            OrderDate = order.OrderDate,
            SalesOrderNumber = order.SalesOrderNumber
        };

    foreach (var onlineOrder in onlineOrders)
    {
        Console.WriteLine("Order ID: {0} Order date: {1:d} Order number: {2}",
            onlineOrder.SalesOrderID,
            onlineOrder.OrderDate,
            onlineOrder.SalesOrderNumber);
    }
}

Example

The following example returns the orders where the order quantity is greater than 2 and less than 6.

C#
int orderQtyMin = 2;
int orderQtyMax = 6;
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var query =
        from order in context.SalesOrderDetails
        where order.OrderQty > orderQtyMin && order.OrderQty < orderQtyMax
        select new
        {
            SalesOrderID = order.SalesOrderID,
            OrderQty = order.OrderQty
        };

    foreach (var order in query)
    {
        Console.WriteLine("Order ID: {0} Order quantity: {1}",
            order.SalesOrderID, order.OrderQty);
    }
}

Example

The following example returns all red colored products.

C#
String color = "Red";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var query =
        from product in context.Products
        where product.Color == color
        select new
        {
            Name = product.Name,
            ProductNumber = product.ProductNumber,
            ListPrice = product.ListPrice
        };

    foreach (var product in query)
    {
        Console.WriteLine("Name: {0}", product.Name);
        Console.WriteLine("Product number: {0}", product.ProductNumber);
        Console.WriteLine("List price: ${0}", product.ListPrice);
        Console.WriteLine("");
    }
}

Example

The following example uses the Where method to find orders that were made after December 1, 2003, and then uses the order.SalesOrderDetail navigation property to get the details for each order.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<SalesOrderHeader> query =
        from order in context.SalesOrderHeaders
        where order.OrderDate >= new DateTime(2003, 12, 1)
        select order;


    Console.WriteLine("Orders that were made after December 1, 2003:");
    foreach (SalesOrderHeader order in query)
    {
        Console.WriteLine("OrderID {0} Order date: {1:d} ",
            order.SalesOrderID, order.OrderDate);
        foreach (SalesOrderDetail orderDetail in order.SalesOrderDetails)
        {
            Console.WriteLine("  Product ID: {0} Unit Price {1}",
                orderDetail.ProductID, orderDetail.UnitPrice);
        }
    }
}

Where…Contains

Example

The following example uses an array as part of a Where…Contains clause to find all products that have a ProductModelID that matches a value in the array.

C#
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    int?[] productModelIds = {19, 26, 118};
    var products = from p in AWEntities.Products
                   where productModelIds.Contains(p.ProductModelID)
                   select p;
    foreach (var product in products)
    {
        Console.WriteLine("{0}: {1}", product.ProductModelID, product.ProductID);
    }
}

Note

As part of the predicate in a Where…Contains clause, you can use an Array, a List<T>, or a collection of any type that implements the IEnumerable<T> interface. You can also declare and initialize a collection within a LINQ to Entities query. See the next example for more information.

Example

The following example declares and initializes arrays in a Where…Contains clause to find all products that have a ProductModelID or Size that match values in the arrays.

C#
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    var products = from p in AWEntities.Products
                   where (new int?[] { 19, 26, 18 }).Contains(p.ProductModelID) ||
                         (new string[] { "L", "XL" }).Contains(p.Size)
                   select p;
    foreach (var product in products)
    {
        Console.WriteLine("{0}: {1}, {2}", product.ProductID, 
                                           product.ProductModelID, 
                                           product.Size);
    }
}

See also

Query Expression Syntax Examples: Ordering

The examples in this topic demonstrate how to use the OrderBy and OrderByDescending methods to query the AdventureWorks Sales Model using query expression syntax. The AdventureWorks Sales Model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

OrderBy

Example

The following example uses OrderBy to return a list of contacts ordered by last name.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<Contact> sortedNames =
        from n in context.Contacts
        orderby n.LastName
        select n;

    Console.WriteLine("The sorted list of last names:");
    foreach (Contact n in sortedNames)
    {
        Console.WriteLine(n.LastName);
    }
}

Example

The following example uses OrderBy to sort a list of contacts by length of last name.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<Contact> sortedNames =
        from n in context.Contacts
        orderby n.LastName.Length
        select n;

    Console.WriteLine("The sorted list of last names (by length):");
    foreach (Contact n in sortedNames)
    {
        Console.WriteLine(n.LastName);
    }
}

OrderByDescending

Example

The following example uses orderby… descending (Order By … Descending in Visual Basic), which is equivalent to the OrderByDescending method, to sort the price list from highest to lowest.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<Decimal> sortedPrices =
        from p in context.Products
        orderby p.ListPrice descending
        select p.ListPrice;

    Console.WriteLine("The list price from highest to lowest:");
    foreach (Decimal price in sortedPrices)
    {
        Console.WriteLine(price);
    }
}

ThenBy

Example

The following example uses OrderBy and ThenBy to return a list of contacts ordered by last name and then by first name.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<Contact> sortedContacts =
        from contact in context.Contacts
        orderby contact.LastName, contact.FirstName
        select contact;

    Console.WriteLine("The list of contacts sorted by last name then by first name:");
    foreach (Contact sortedContact in sortedContacts)
    {
        Console.WriteLine(sortedContact.LastName + ", " + sortedContact.FirstName);
    }
}

ThenByDescending

Example

The following example uses OrderBy… Descending, which is equivalent to the ThenByDescending method, to sort a list of products, first by name and then by list price from highest to lowest.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<Product> query =
        from product in context.Products
        orderby product.Name, product.ListPrice descending
        select product;

    foreach (Product product in query)
    {
        Console.WriteLine("Product ID: {0} Product Name: {1} List Price {2}",
            product.ProductID,
            product.Name,
            product.ListPrice);
    }
}

See also

Query Expression Syntax Examples: Aggregate Operators

The examples in this topic demonstrate how to use the Average, Count, Max, Min, and Sum methods to query the AdventureWorks Sales Model using query expression syntax. The AdventureWorks Sales Model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

Average

Example

The following example uses the Average method to find the average list price of the products of each style.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Product> products = context.Products;

    var query = from product in products
                group product by product.Style into g
                select new
                {
                    Style = g.Key,
                    AverageListPrice =
                        g.Average(product => product.ListPrice)
                };

    foreach (var product in query)
    {
        Console.WriteLine("Product style: {0} Average list price: {1}",
            product.Style, product.AverageListPrice);
    }
}

Example

The following example uses Average to get the average total due for each contact ID.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from order in orders
        group order by order.Contact.ContactID into g
        select new
        {
            Category = g.Key,
            averageTotalDue = g.Average(order => order.TotalDue)
        };

    foreach (var order in query)
    {
        Console.WriteLine("ContactID = {0} \t Average TotalDue = {1}",
            order.Category, order.averageTotalDue);
    }
}

Example

The following example uses Average to get the orders with the average total due for each contact.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from order in orders
        group order by order.Contact.ContactID into g
        let averageTotalDue = g.Average(order => order.TotalDue)
        select new
        {
            Category = g.Key,
            CheapestProducts =
                g.Where(order => order.TotalDue == averageTotalDue)
        };

    foreach (var orderGroup in query)
    {
        Console.WriteLine("ContactID: {0}", orderGroup.Category);
        foreach (var order in orderGroup.CheapestProducts)
        {
            Console.WriteLine("Average total due for SalesOrderID {1} is: {0}",
                order.TotalDue, order.SalesOrderID);
        }
        Console.Write("\n");
    }
}

Count

Example

The following example uses Count to return a list of contact IDs and how many orders each has.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;

    //Can't find field SalesOrderContact
    var query =
        from contact in contacts
        select new
        {
            CustomerID = contact.ContactID,
            OrderCount = contact.SalesOrderHeaders.Count()
        };

    foreach (var contact in query)
    {
        Console.WriteLine("CustomerID = {0} \t OrderCount = {1}",
            contact.CustomerID,
            contact.OrderCount);
    }
}

Example

The following example groups products by color and uses Count to return the number of products in each color group.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Product> products = context.Products;

    var query =
        from product in products
        group product by product.Color into g
        select new { Color = g.Key, ProductCount = g.Count() };

    foreach (var product in query)
    {
        Console.WriteLine("Color = {0} \t ProductCount = {1}",
            product.Color,
            product.ProductCount);
    }
}

Max

Example

The following example uses the Max method to get the largest total due for each contact ID.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from order in orders
        group order by order.Contact.ContactID into g
        select new
        {
            Category = g.Key,
            maxTotalDue =
                g.Max(order => order.TotalDue)
        };

    foreach (var order in query)
    {
        Console.WriteLine("ContactID = {0} \t Maximum TotalDue = {1}",
            order.Category, order.maxTotalDue);
    }
}

Example

The following example uses the Max method to get the orders with the largest total due for each contact ID.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from order in orders
        group order by order.Contact.ContactID into g
        let maxTotalDue = g.Max(order => order.TotalDue)
        select new
        {
            Category = g.Key,
            CheapestProducts =
                g.Where(order => order.TotalDue == maxTotalDue)
        };

    foreach (var orderGroup in query)
    {
        Console.WriteLine("ContactID: {0}", orderGroup.Category);
        foreach (var order in orderGroup.CheapestProducts)
        {
            Console.WriteLine("MaxTotalDue {0} for SalesOrderID {1}: ",
                order.TotalDue,
                order.SalesOrderID);
        }
        Console.Write("\n");
    }
}

Min

Example

The following example uses the Min method to get the smallest total due for each contact ID.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from order in orders
        group order by order.Contact.ContactID into g
        select new
        {
            Category = g.Key,
            smallestTotalDue =
                g.Min(order => order.TotalDue)
        };

    foreach (var order in query)
    {
        Console.WriteLine("ContactID = {0} \t Minimum TotalDue = {1}",
            order.Category, order.smallestTotalDue);
    }
}

Example

The following example uses the Min method to get the orders with the smallest total due for each contact.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from order in orders
        group order by order.Contact.ContactID into g
        let minTotalDue = g.Min(order => order.TotalDue)
        select new
        {
            Category = g.Key,
            smallestTotalDue =
                g.Where(order => order.TotalDue == minTotalDue)
        };


    foreach (var orderGroup in query)
    {
        Console.WriteLine("ContactID: {0}", orderGroup.Category);
        foreach (var order in orderGroup.smallestTotalDue)
        {
            Console.WriteLine("Mininum TotalDue {0} for SalesOrderID {1}: ",
                order.TotalDue,
                order.SalesOrderID);
        }
        Console.Write("\n");
    }
}

Sum

Example

The following example uses the Sum method to get the total due for each contact ID.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from order in orders
        group order by order.Contact.ContactID into g
        select new
        {
            Category = g.Key,
            TotalDue = g.Sum(order => order.TotalDue)
        };

    foreach (var order in query)
    {
        Console.WriteLine("ContactID = {0} \t TotalDue sum = {1}",
            order.Category, order.TotalDue);
    }
}

See also

Query Expression Syntax Examples: Partitioning

The examples in this topic demonstrate how to use the Skip and Take methods to query the AdventureWorks Sales Model using query expression syntax. The AdventureWorks Sales Model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

Skip

Example

The following example uses the Skip method to get all but the first two addresses in Seattle.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Address> addresses = context.Addresses;
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    //LINQ to Entities only supports Skip on ordered collections.
    var query = (
        from address in addresses
        from order in orders
        where address.AddressID == order.Address.AddressID
             && address.City == "Seattle"
        orderby order.SalesOrderID
        select new
        {
            City = address.City,
            OrderID = order.SalesOrderID,
            OrderDate = order.OrderDate
        }).Skip(2);

    Console.WriteLine("All but first 2 orders in Seattle:");
    foreach (var order in query)
    {
        Console.WriteLine("City: {0} Order ID: {1} Total Due: {2:d}",
            order.City, order.OrderID, order.OrderDate);
    }

Take

Example

The following example uses the Take method to get the first three addresses in Seattle.

C#
String city = "Seattle";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Address> addresses = context.Addresses;
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query = (
        from address in addresses
        from order in orders
        where address.AddressID == order.Address.AddressID
             && address.City == city
        select new
        {
            City = address.City,
            OrderID = order.SalesOrderID,
            OrderDate = order.OrderDate
        }).Take(3);
    Console.WriteLine("First 3 orders in Seattle:");
    foreach (var order in query)
    {
        Console.WriteLine("City: {0} Order ID: {1} Total Due: {2:d}",
            order.City, order.OrderID, order.OrderDate);
    }
}

See also

Query Expression Syntax Examples: Join Operators

Joining is an important operation in queries that target data sources that have no navigable relationships to each other, such as relational database tables. A join of two data sources is the association of objects in one data source with objects that share a common attribute in the other data source. For more information, see Standard Query Operators Overview.

The examples in this topic demonstrate how to use the GroupJoin and Join methods to query the AdventureWorks Sales Model using query expression syntax. The AdventureWorks Sales Model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

GroupJoin

Example

The following example performs a GroupJoin over the SalesOrderHeader and SalesOrderDetail tables to find the number of orders per customer. A group join is the equivalent of a left outer join, which returns each element of the first (left) data source, even if no correlated elements are in the other data source.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;
    ObjectSet<SalesOrderDetail> details = context.SalesOrderDetails;

    var query =
        from order in orders
        join detail in details
        on order.SalesOrderID
        equals detail.SalesOrderID into orderGroup
        select new
        {
            CustomerID = order.SalesOrderID,
            OrderCount = orderGroup.Count()
        };

    foreach (var order in query)
    {
        Console.WriteLine("CustomerID: {0}  Orders Count: {1}",
            order.CustomerID,
            order.OrderCount);
    }
}

Example

The following example performs a GroupJoin over the Contact and SalesOrderHeader tables to find the number of orders per contact. The order count and IDs for each contact are displayed.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var query =
        from contact in contacts
        join order in orders
        on contact.ContactID
        equals order.Contact.ContactID into contactGroup
        select new
        {
            ContactID = contact.ContactID,
            OrderCount = contactGroup.Count(),
            Orders = contactGroup
        };

    foreach (var group in query)
    {
        Console.WriteLine("ContactID: {0}", group.ContactID);
        Console.WriteLine("Order count: {0}", group.OrderCount);
        foreach (var orderInfo in group.Orders)
        {
            Console.WriteLine("   Sale ID: {0}", orderInfo.SalesOrderID);
        }
        Console.WriteLine("");
    }
}

Join

Example

The following example performs a join over the SalesOrderHeader and SalesOrderDetail tables to get online orders from the month of August.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;
    ObjectSet<SalesOrderDetail> details = context.SalesOrderDetails;

    var query =
        from order in orders
        join detail in details
        on order.SalesOrderID equals detail.SalesOrderID
        where order.OnlineOrderFlag == true
        && order.OrderDate.Month == 8
        select new
        {
            SalesOrderID = order.SalesOrderID,
            SalesOrderDetailID = detail.SalesOrderDetailID,
            OrderDate = order.OrderDate,
            ProductID = detail.ProductID
        };

    foreach (var order in query)
    {
        Console.WriteLine("{0}\t{1}\t{2:d}\t{3}",
            order.SalesOrderID,
            order.SalesOrderDetailID,
            order.OrderDate,
            order.ProductID);
    }
}

See also

Query Expression Syntax Examples: Element Operators

The examples in this topic demonstrate how to use the First method to query the AdventureWorks Sales Model using the query expression syntax. The AdventureWorks Sales Model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

First

Example

The following example uses the First method to return the first contact whose first name is "Brooke".

C#
string firstName = "Brooke";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;

    Contact query = (
        from contact in contacts
        where contact.FirstName == firstName
        select contact)
        .First();

    Console.WriteLine("ContactID: " + query.ContactID);
    Console.WriteLine("FirstName: " + query.FirstName);
    Console.WriteLine("LastName: " + query.LastName);
}

See also

Query Expression Syntax Examples: Grouping

The examples in this topic demonstrate how to use the GroupBy method to query the AdventureWorks Sales Model using query expression syntax. The AdventureWorks Sales model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

Example

The following example returns Address objects grouped by postal code. The results are projected into an anonymous type.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var query =
        from address in context.Addresses
        group address by address.PostalCode into addressGroup
        select new { PostalCode = addressGroup.Key, 
                     AddressLine = addressGroup };

    foreach (var addressGroup in query)
    {
        Console.WriteLine("Postal Code: {0}", addressGroup.PostalCode);
        foreach (var address in addressGroup.AddressLine)
        {
            Console.WriteLine("\t" + address.AddressLine1 +
                address.AddressLine2);
        }
    }
}

Example

The following example returns Contact objects grouped by the first letter of the contact's last name. The results are also sorted by the first letter of last name and projected into an anonymous type.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var query = (
        from contact in context.Contacts
        group contact by contact.LastName.Substring(0, 1) into contactGroup
        select new { FirstLetter = contactGroup.Key, Names = contactGroup }).
            OrderBy(letter => letter.FirstLetter);

    foreach (var contact in query)
    {
        Console.WriteLine("Last names that start with the letter '{0}':",
            contact.FirstLetter);
        foreach (var name in contact.Names)
        {
            Console.WriteLine(name.LastName);
        }
    }
}

Example

The following example returns SalesOrderHeader objects grouped by customer ID. The number of sales for each customer is also returned.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var query = from order in context.SalesOrderHeaders
                group order by order.CustomerID into idGroup 
                select new {CustomerID = idGroup.Key, 
                    OrderCount = idGroup.Count(),
                    Sales = idGroup};

    foreach (var orderGroup in query)
    {
        Console.WriteLine("Customer ID: {0}", orderGroup.CustomerID);
        Console.WriteLine("Order Count: {0}", orderGroup.OrderCount);

        foreach (SalesOrderHeader sale in orderGroup.Sales)
        {
            Console.WriteLine("   Sale ID: {0}", sale.SalesOrderID);
        }

        Console.WriteLine("");
    }
}

See also

Query Expression Syntax Examples: Navigating Relationships

Navigation properties in the Entity Framework are shortcut properties used to locate the entities at the ends of an association. Navigation properties allow a user to navigate from one entity to another, or from one entity to related entities through an association set. This topic provides examples in query expression syntax of how to navigate relationships through navigation properties in LINQ to Entities queries.

The AdventureWorks Sales Model used in these examples is built from the Contact, Address, Product, SalesOrderHeader, and SalesOrderDetail tables in the AdventureWorks sample database.

The examples in this topic use the following using/Imports statements:

C#
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

Example

The following example uses the Select method to get all the contact IDs and the sum of the total due for each contact whose last name is "Zhou". The Contact.SalesOrderHeader navigation property is used to get the collection of SalesOrderHeader objects for each contact. The Sum method uses the Contact.SalesOrderHeader navigation property to sum the total due of all the orders for each contact.

C#
string lastName = "Zhou";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;

    var ordersQuery = from contact in contacts
                      where contact.LastName == lastName
                      select new
                      {
                          ContactID = contact.ContactID,
                          Total = contact.SalesOrderHeaders.Sum(o => o.TotalDue)
                      };

    foreach (var contact in ordersQuery)
    {
        Console.WriteLine("Contact ID: {0} Orders total: {1}", contact.ContactID, contact.Total);
    }
}

Example

The following example gets all the orders of the contacts whose last name is "Zhou". The Contact.SalesOrderHeader navigation property is used to get the collection of SalesOrderHeader objects for each contact. The contact's name and orders are returned in an anonymous type.

C#
string lastName = "Zhou";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;

    var ordersQuery = from contact in contacts
                      where contact.LastName == lastName
                      select new { LastName = contact.LastName, Orders = contact.SalesOrderHeaders };

    foreach (var order in ordersQuery)
    {
        Console.WriteLine("Name: {0}", order.LastName);
        foreach (SalesOrderHeader orderInfo in order.Orders)
        {
            Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}",
                orderInfo.SalesOrderID, orderInfo.OrderDate, orderInfo.TotalDue);
        }
        Console.WriteLine("");
    }
}

Example

The following example uses the SalesOrderHeader.Address and SalesOrderHeader.Contact navigation properties get the collection of Address and Contact objects associated with each order. The last name of the contact, the street address, the sales order number, and the total due for each order to the city of Seattle are returned in an anonymous type.

C#
string city = "Seattle";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;

    var ordersQuery = from order in orders
                      where order.Address.City == city
                      select new
                      {
                          ContactLastName = order.Contact.LastName,
                          ContactFirstName = order.Contact.FirstName,
                          StreetAddress = order.Address.AddressLine1,
                          OrderNumber = order.SalesOrderNumber,
                          TotalDue = order.TotalDue
                      };

    foreach (var orderInfo in ordersQuery)
    {
        Console.WriteLine("Name: {0}, {1}", orderInfo.ContactLastName, orderInfo.ContactFirstName);
        Console.WriteLine("Street address: {0}", orderInfo.StreetAddress);
        Console.WriteLine("Order number: {0}", orderInfo.OrderNumber);
        Console.WriteLine("Total Due: {0}", orderInfo.TotalDue);
        Console.WriteLine("");
    }
}

Example

The following example uses the Where method to find orders that were made after December 1, 2003, and then uses the order.SalesOrderDetail navigation property to get the details for each order.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<SalesOrderHeader> query =
        from order in context.SalesOrderHeaders
        where order.OrderDate >= new DateTime(2003, 12, 1)
        select order;


    Console.WriteLine("Orders that were made after December 1, 2003:");
    foreach (SalesOrderHeader order in query)
    {
        Console.WriteLine("OrderID {0} Order date: {1:d} ",
            order.SalesOrderID, order.OrderDate);
        foreach (SalesOrderDetail orderDetail in order.SalesOrderDetails)
        {
            Console.WriteLine("  Product ID: {0} Unit Price {1}",
                orderDetail.ProductID, orderDetail.UnitPrice);
        }
    }
}

See also

Expressions in LINQ to Entities Queries

An expression is a fragment of code that can be evaluated to a single value, object, method, or namespace. Expressions can contain a literal value, a method call, an operator and its operands, or a simple name. Simple names can be the name of a variable, type member, method parameter, namespace or type. Expressions can use operators that in turn use other expressions as parameters, or method calls whose parameters are in turn other method calls. Therefore, expressions can range from simple to very complex.

In LINQ to Entities queries, expressions can contain anything allowed by the types within the System.Linq.Expressions namespace, including lambda expressions. The expressions that can be used in LINQ to Entities queries are a superset of the expressions that can be used to query the Entity Framework. Expressions that are part of queries against the Entity Framework are limited to operations supported by ObjectQuery<T> and the underlying data source.

In the following example, the comparison in the Where clause is an expression:

C#
Decimal totalDue = 200;
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<int> salesInfo =
        from s in context.SalesOrderHeaders
        where s.TotalDue >= totalDue
        select s.SalesOrderID;

    Console.WriteLine("Sales order info:");
    foreach (int orderNumber in salesInfo)
    {
        Console.WriteLine("Order number: " + orderNumber);                    
    }
}

Note

Specific language constructs, such as C# unchecked, have no meaning in LINQ to Entities.

In This Section

Constant Expressions

Comparison Expressions

Null Comparisons

Initialization Expressions

Relationships, navigation properties and foreign keys

See also

Constant Expressions

A constant expression consists of a constant value. Constant values are directly converted to constant command tree expressions, without any translation on the client. This includes expressions that result in a constant value. Therefore, data source behavior should be expected for all expressions involving constants. This can result in behavior that differs from CLR behavior.

The following example shows a constant expression that is evaluated on the server.

C#
Decimal totalDue = 200 + 3;
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<string> salesInfo =
        from s in context.SalesOrderHeaders
        where s.TotalDue >= totalDue
        select s.SalesOrderNumber;

    Console.WriteLine("Sales order numbers:");
    foreach (string orderNum in salesInfo)
    {
        Console.WriteLine(orderNum);
    }
}

LINQ to Entities does not support using a user class as a constant. However, a property reference on a user class is considered a constant, and will be converted to a command tree constant expression and executed on the data source.

See also

Comparison Expressions

A comparison expression checks whether a constant value, property value, or method result is equal, not equal, greater than, or less than another value. If a particular comparison is not valid for LINQ to Entities, an exception will be thrown. All comparisons, both implicit and explicit, require that all components are comparable in the data source. Comparison expressions are frequently used in Where clauses for restricting the query results.

The following example in query expression syntax shows a query that returns results where the sales order number is equal to "SO43663":

C#
string salesOrderNumber = "SO43663";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<SalesOrderHeader> salesInfo =
        from s in context.SalesOrderHeaders
        where s.SalesOrderNumber == salesOrderNumber
        select s;

    Console.WriteLine("Sales info-");
    foreach (SalesOrderHeader sale in salesInfo)
    {
        Console.WriteLine("Sales ID: " + sale.SalesOrderID);
        Console.WriteLine("Ship date: " + sale.ShipDate);
    }
}

The following example in method-based query syntax shows a query that returns results where the sales order number is equal to "SO43663":

C#
    string salesOrderNumber = "SO43663";
    IQueryable<SalesOrderHeader> salesInfo =
        context.SalesOrderHeaders
        .Where(s => s.SalesOrderNumber == salesOrderNumber)
        .Select(s => s);

    Console.WriteLine("Sales info-");
    foreach (SalesOrderHeader sale in salesInfo)
    {
        Console.WriteLine("Sales ID: " + sale.SalesOrderID);
        Console.WriteLine("Ship date: " + sale.ShipDate);
    }
}

The following example in query expression syntax shows a query that returns sales order information where the ship date is equal to July 8, 2001:

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    DateTime dt = new DateTime(2001, 7, 8);

    IQueryable<SalesOrderHeader> salesInfo =
        from s in context.SalesOrderHeaders
        where s.ShipDate == dt
        select s;

    Console.WriteLine("Orders shipped on August 7, 2001:");
    foreach (SalesOrderHeader sale in salesInfo)
    {
        Console.WriteLine("Sales ID: " + sale.SalesOrderID);
        Console.WriteLine("Total due: " + sale.TotalDue);
        Console.WriteLine();
    }
}

The following example in method-based query syntax shows a query that returns sales order information where the ship date is equal to July 8, 2001:

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    DateTime dt = new DateTime(2001, 7, 8);

    IQueryable<SalesOrderHeader> salesInfo =
        context.SalesOrderHeaders
        .Where(s => s.ShipDate == dt)
        .Select(s => s);

    Console.WriteLine("Orders shipped on August 7, 2001:");
    foreach (SalesOrderHeader sale in salesInfo)
    {
        Console.WriteLine("Sales ID: " + sale.SalesOrderID);
        Console.WriteLine("Total due: " + sale.TotalDue);
        Console.WriteLine();
    }
}

Expressions that yield a constant are converted at the server, and no attempt to do local evaluation is performed. The following example uses an expression in the Where clause that yields a constant.

C#
Decimal totalDue = 200 + 3;
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<string> salesInfo =
        from s in context.SalesOrderHeaders
        where s.TotalDue >= totalDue
        select s.SalesOrderNumber;

    Console.WriteLine("Sales order numbers:");
    foreach (string orderNum in salesInfo)
    {
        Console.WriteLine(orderNum);
    }
}

LINQ to Entities does not support using a user class as a constant. However, a property reference on a user class is considered a constant, and will be converted to a command tree constant expression and executed on the data source.

C#
class AClass { public int ID;}
C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    AClass aClass = new AClass();
    aClass.ID = 43663;

    IQueryable<SalesOrderHeader> salesInfo =
        from s in context.SalesOrderHeaders
        where s.SalesOrderID == aClass.ID
        select s;

    Console.WriteLine("Order info-");
    foreach (SalesOrderHeader sale in salesInfo)
    {
        Console.WriteLine("Sales order number: " + sale.SalesOrderNumber);
        Console.WriteLine("Total due: " + sale.TotalDue);
        Console.WriteLine();
    }
}

Methods that return a constant expression are not supported. The following example contains a method in the Where clause that returns a constant. This example will throw an exception at run time.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    MyClass2 myClass = new MyClass2();


    //Throws a NotSupportedException
    IQueryable<SalesOrderHeader> salesInfo =
        from s in context.SalesOrderHeaders
        where s.SalesOrderID == myClass.returnInt()
        select s;

    Console.WriteLine("Order info-");
    try
    {
        foreach (SalesOrderHeader sale in salesInfo)
        {
            Console.WriteLine("Sales order number: " + sale.SalesOrderNumber);
            Console.WriteLine("Total due: " + sale.TotalDue);
            Console.WriteLine();
        }
    }
    catch (NotSupportedException ex)
    {
        Console.WriteLine("Exception: {0}", ex.Message);
    }
}

See also

Null Comparisons

A null value in the data source indicates that the value is unknown. In LINQ to Entities queries, you can check for null values so that certain calculations or comparisons are only performed on rows that have valid, or non-null, data. CLR null semantics, however, may differ from the null semantics of the data source. Most databases use a version of three-valued logic to handle null comparisons. That is, a comparison against a null value does not evaluate to true or false, it evaluates to unknown. Often this is an implementation of ANSI nulls, but this is not always the case.

By default in SQL Server, the null-equals-null comparison returns a null value. In the following example, the rows where ShipDate is null are excluded from the result set, and the Transact-SQL statement would return 0 rows.

-- Find order details and orders with no ship date.  
SELECT h.SalesOrderID  
FROM Sales.SalesOrderHeader h  
JOIN Sales.SalesOrderDetail o ON o.SalesOrderID = h.SalesOrderID  
WHERE h.ShipDate IS Null  

This is very different from the CLR null semantics, where the null-equals-null comparison returns true.

The following LINQ query is expressed in the CLR, but it is executed in the data source. Because there is no guarantee that CLR semantics will be honored at the data source, the expected behavior is indeterminate.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;
    ObjectSet<SalesOrderDetail> details = context.SalesOrderDetails;

    var query =
        from order in orders 
        join detail in details 
        on order.SalesOrderID 
        equals detail.SalesOrderID 
        where order.ShipDate == null
        select order.SalesOrderID;

    foreach (var OrderID in query)
    {
        Console.WriteLine("OrderID : {0}", OrderID);
    }
}

Key Selectors

A key selector is a function used in the standard query operators to extract a key from an element. In the key selector function, an expression can be compared with a constant. CLR null semantics are exhibited if an expression is compared to a null constant or if two null constants are compared. Store null semantics are exhibited if two columns with null values in the data source are compared. Key selectors are found in many of the grouping and ordering standard query operators, such as GroupBy, and are used to select keys by which to order or group the query results.

Null Property on a Null Object

In the Entity Framework, the properties of a null object are null. When you attempt to reference a property of a null object in the CLR, you will receive a NullReferenceException. When a LINQ query involves a property of a null object, this can result in inconsistent behavior.

For example, in the following query, the cast to NewProduct is done in the command tree layer, which might result in the Introduced property being null. If the database defined null comparisons such that the DateTime comparison evaluates to true, the row will be included.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{

    DateTime dt = new DateTime();
    var query = context.Products
        .Where(p => (p as NewProduct).Introduced > dt)
        .Select(x => x);
}

Passing Null Collections to Aggregate Functions

In LINQ to Entities, when you pass a collection that supports IQueryable to an aggregate function, aggregate operations are performed at the database. There might be differences in the results of a query that was performed in-memory and a query that was performed at the database. With an in-memory query, if there are no matches, the query returns zero. At the database, the same query returns null. If a null value is passed to a LINQ aggregate function, an exception will be thrown. To accept possible null values, cast the types and the properties of the types that receive query results to nullable types.

See also

Initialization Expressions

An initialization expression initializes a new object. Most initialization expressions are supported, including most new C# 3.0 and Visual Basic 9.0 initialization expressions. The following types can be initialized and returned by a LINQ to Entities query:

  • A collection of zero or more typed entity objects or a projection of complex types that are defined in the conceptual model.

  • CLR types supported by the Entity Framework.

  • Inline collections.

  • Anonymous types.

Anonymous type initialization is shown in the following example in query expression syntax:

C#
Decimal totalDue = 200;
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var salesInfo =
        from s in context.SalesOrderHeaders
        where s.TotalDue >= totalDue
        select new { s.SalesOrderNumber, s.TotalDue };

    Console.WriteLine("Sales order numbers:");
    foreach (var sale in salesInfo)
    {
        Console.WriteLine("Order number: " + sale.SalesOrderNumber);
        Console.WriteLine("Total due: " + sale.TotalDue);
        Console.WriteLine("");
    }
}

The following example in method-based query syntax shows anonymous type initialization:

C#
Decimal totalDue = 200;
using (AdventureWorksEntities context = new AdventureWorksEntities())
{

    var salesInfo =
        context.SalesOrderHeaders
        .Where(s => s.TotalDue >= totalDue)
        .Select(s => new { s.SalesOrderNumber, s.TotalDue });

    Console.WriteLine("Sales order numbers:");
    foreach (var sale in salesInfo)
    {
        Console.WriteLine("Order number: " + sale.SalesOrderNumber);
        Console.WriteLine("Total due: " + sale.TotalDue);
        Console.WriteLine("");
    }
}

User-defined class initialization is also supported. The C# 3.0 and Visual Basic 9.0 initialization pattern is supported and assumes that the property getter and setter are symmetric. The following example in query expression syntax shows a custom class being initialized in the query:

C#
class MyOrder { public string SalesOrderNumber; public DateTime? ShipDate; }
C#
Decimal totalDue = 200;
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<MyOrder> salesInfo =
        from s in context.SalesOrderHeaders
        where s.TotalDue >= totalDue
        select new MyOrder
        {
            SalesOrderNumber = s.SalesOrderNumber,
            ShipDate = s.ShipDate
        };

    Console.WriteLine("Sales order info:");
    foreach (MyOrder order in salesInfo)
    {
        Console.WriteLine("Order number: " + order.SalesOrderNumber);
        Console.WriteLine("Ship date: " + order.ShipDate);
        Console.WriteLine("");
    }
}

The following example in method-based query syntax shows a custom class being initialized in the query:

C#
Decimal totalDue = 200;
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<MyOrder> salesInfo =
        context.SalesOrderHeaders
        .Where(s => s.TotalDue >= totalDue)
        .Select(s => new MyOrder
        {
            SalesOrderNumber = s.SalesOrderNumber,
            ShipDate = s.ShipDate
        });

    Console.WriteLine("Sales order info:");
    foreach (MyOrder order in salesInfo)
    {
        Console.WriteLine("Order number: " + order.SalesOrderNumber);
        Console.WriteLine("Ship date: " + order.ShipDate);
        Console.WriteLine("");
    }
}

See also

Calling Functions in LINQ to Entities Queries

The topics in this section describe how to call functions in LINQ to Entities queries.

The EntityFunctions and SqlFunctions classes provide access to canonical and database functions as part of the Entity Framework. For more information, see How to: Call Canonical Functions and How to: Call Database Functions.

The process for calling a custom function requires three basic steps:

  1. Define a function in your conceptual model or declare a function in your storage model.

  2. Add a method to your application and map it to the function in the model with an EdmFunctionAttribute.

  3. Call the function in a LINQ to Entities query.

For more information, see the topics in this section.

In This Section

How to: Call Canonical Functions

How to: Call Database Functions

How to: Call Custom Database Functions

How to: Call Model-Defined Functions in Queries

How to: Call Model-Defined Functions as Object Methods

See also

How to: Call Canonical Functions

The EntityFunctions class contains methods that expose canonical functions to use in LINQ to Entities queries. For information about canonical functions, see Canonical Functions.

Note

The AsUnicode and AsNonUnicode methods in the EntityFunctions class do not have canonical function equivalents.

Canonical functions that perform a calculation on a set of values and return a single value (also known as aggregate canonical functions) can be directly invoked. Other canonical functions can only be called as part of a LINQ to Entities query. To call an aggregate function directly, you must pass an ObjectQuery<T> to the function. For more information, see the second example below.

You can call some canonical functions by using common language runtime (CLR) methods in LINQ to Entities queries. For a list of CLR methods that map to canonical functions, see CLR Method to Canonical Function Mapping.

Example

The following example uses the AdventureWorks Sales Model. The example executes a LINQ to Entities query that uses the DiffDays method to return all products for which the difference between SellEndDate and SellStartDate is less than 365 days:

C#
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    var products = from p in AWEntities.Products
                   where EntityFunctions.DiffDays(p.SellEndDate, p.SellStartDate) < 365
                   select p;
    foreach (var product in products)
    {
        Console.WriteLine(product.ProductID);
    }
}

Example

The following example uses the AdventureWorks Sales Model. The example calls the aggregate StandardDeviation method directly to return the standard deviation of SalesOrderHeader subtotals. Note that an ObjectQuery<T> is passed to the function, which allows it to be called without being part of a LINQ to Entities query.

C#
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    double? stdDev = EntityFunctions.StandardDeviation(
        from o in AWEntities.SalesOrderHeaders
        select o.SubTotal);

    Console.WriteLine(stdDev);
}

See also

How to: Call Database Functions

The SqlFunctions class contains methods that expose SQL Server functions to use in LINQ to Entities queries. When you use SqlFunctions methods in LINQ to Entities queries, the corresponding database functions are executed in the database.

Note

Database functions that perform a calculation on a set of values and return a single value (also known as aggregate database functions) can be directly invoked. Other canonical functions can only be called as part of a LINQ to Entities query. To call an aggregate function directly, you must pass an ObjectQuery<T> to the function. For more information, see the second example below.

Note

The methods in the SqlFunctions class are specific to SQL Server functions. Similar classes that expose database functions may be available through other providers.

Example

The following example uses the AdventureWorks Sales Model. The example executes a LINQ to Entities query that uses the CharIndex method to return all contacts whose last name starts with "Si":

C#
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    // SqlFunctions.CharIndex is executed in the database.
    var contacts = from c in AWEntities.Contacts
                   where SqlFunctions.CharIndex("Si", c.LastName) == 1
                   select c;

    foreach (var contact in contacts)
    {
        Console.WriteLine(contact.LastName);
    }
}

Example

The following example uses the AdventureWorks Sales Model. The example calls the aggregate ChecksumAggregate method directly. Note that an ObjectQuery<T> is passed to the function, which allows it to be called without being part of a LINQ to Entities query.

C#
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    // SqlFunctions.ChecksumAggregate is executed in the database.
    decimal? checkSum = SqlFunctions.ChecksumAggregate(
        from o in AWEntities.SalesOrderHeaders
        select o.SalesOrderID);

    Console.WriteLine(checkSum);
}

See also

How to: Call Custom Database Functions

This topic describes how to call custom functions that are defined in the database from within LINQ to Entities queries.

Database functions that are called from LINQ to Entities queries are executed in the database. Executing functions in the database can improve application performance.

The procedure below provides a high-level outline for calling a custom database function. The example that follows provides more detail about the steps in the procedure.

To call custom functions that are defined in the database

  1. Create a custom function in your database.

    For more information about creating custom functions in SQL Server, see CREATE FUNCTION (Transact-SQL).

  2. Declare a function in the store schema definition language (SSDL) of your .edmx file. The name of the function must be the same as the name of the function declared in the database.

    For more information, see Function Element (SSDL).

  3. Add a corresponding method to a class in your application code and apply a EdmFunctionAttribute to the method Note that the NamespaceName and FunctionName parameters of the attribute are the namespace name of the conceptual model and the function name in the conceptual model respectively. Function name resolution for LINQ is case sensitive.

  4. Call the method in a LINQ to Entities query.

Example

The following example demonstrates how to call a custom database function from within a LINQ to Entities query. The example uses the School model. For information about the School model, see Creating the School Sample Database and Generating the School .edmx File.

The following code adds the AvgStudentGrade function to the School sample database.

Note

The steps for calling a custom database function are the same regardless of the database server. However, the code below is specific to creating a function in a SQL Server database. The code for creating a custom function in other database servers might differ.

SQL
USE [School]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[AvgStudentGrade](@studentId INT)
RETURNS DECIMAL(3,2)
AS
    BEGIN
    DECLARE @avg DECIMAL(3,2);
    SELECT @avg = avg(Grade) FROM StudentGrade WHERE StudentID = @studentId;

    RETURN @avg;
END

Example

Next, declare a function in the store schema definition language (SSDL) of your .edmx file. the following code declares the AvgStudentGrade function in SSDL:

XML
<Function Name="AvgStudentGrade" ReturnType="decimal" Schema="dbo" >
  <Parameter Name="studentId" Mode="In" Type="int" />
</Function>

Example

Now create a method and map it to the function declared in the SSDL. The method in the following class is mapped to the function defined in the SSDL (above) by using an EdmFunctionAttribute. When this method is called, the corresponding function in the database is executed.

C#
[EdmFunction("SchoolModel.Store", "AvgStudentGrade")]
public static decimal? AvgStudentGrade(int studentId)
{
    throw new NotSupportedException("Direct calls are not supported.");
}

Example

Finally, call the method in a LINQ to Entities query. The following code displays students' last names and average grades to the console:

C#
using (SchoolEntities context = new SchoolEntities())
{
    var students = from s in context.People
                   where s.EnrollmentDate != null
                   select new
                   {
                       name = s.LastName,
                       avgGrade = AvgStudentGrade(s.PersonID)
                   };

    foreach (var student in students)
    {
        Console.WriteLine("{0}: {1}", student.name, student.avgGrade);
    }
}

See also

How to: Call Model-Defined Functions in Queries

This topic describes how to call functions that are defined in the conceptual model from within LINQ to Entities queries.

The procedure below provides a high-level outline for calling a model-defined function from within a LINQ to Entities query. The example that follows provides more detail about the steps in the procedure. The procedure assumes that you have defined a function in the conceptual model. For more information, see How to: Define Custom Functions in the Conceptual Model.

To call a function defined in the conceptual model

  1. Add a common language runtime (CLR) method to your application that maps to the function defined in the conceptual model. To map the method, you must apply an EdmFunctionAttribute to the method. Note that the NamespaceName and FunctionName parameters of the attribute are the namespace name of the conceptual model and the function name in the conceptual model respectively. Function name resolution for LINQ is case sensitive.

  2. Call the function in a LINQ to Entities query.

Example

The following example demonstrates how to call a function that is defined in the conceptual model from within a LINQ to Entities query. The example uses the School model. For information about the School model, see Creating the School Sample Database and Generating the School .edmx File.

The following conceptual model function returns the number of years since an instructor was hired. For information about adding the function to a conceptual model, see How to: Define Custom Functions in the Conceptual Model.)

XML
<Function Name="YearsSince" ReturnType="Edm.Int32">
  <Parameter Name="date" Type="Edm.DateTime" />
  <DefiningExpression>
    Year(CurrentDateTime()) - Year(date)
  </DefiningExpression>
</Function>

Example

Next, add the following method to your application and use an EdmFunctionAttribute to map it to the conceptual model function:

C#
[EdmFunction("SchoolModel", "YearsSince")]
public static int YearsSince(DateTime date)
{
    throw new NotSupportedException("Direct calls are not supported.");
}

Example

Now you can call the conceptual model function from within a LINQ to Entities query. The following code calls the method to display all instructors that were hired more than ten years ago:

C#
using (SchoolEntities context = new SchoolEntities())
{
    // Retrieve instructors hired more than 10 years ago.
    var instructors = from p in context.People
                      where YearsSince((DateTime)p.HireDate) > 10
                      select p;

    foreach (var instructor in instructors)
    {
        Console.WriteLine(instructor.LastName);
    }
}

See also

How to: Call Model-Defined Functions as Object Methods

This topic describes how to call a model-defined function as a method on an ObjectContext object or as a static method on a custom class. A model-defined function is a function that is defined in the conceptual model. The procedures in the topic describe how to call these functions directly instead of calling them from LINQ to Entities queries. For information about calling model-defined functions in LINQ to Entities queries, see How to: Call Model-Defined Functions in Queries.

Whether you call a model-defined function as an ObjectContext method or as a static method on a custom class, you must first map the method to the model-defined function with an EdmFunctionAttribute. However, when you define a method on the ObjectContext class, you must use the QueryProvider property to expose the LINQ provider, whereas when you define a static method on a custom class, you must use the Provider property to expose the LINQ provider. For more information, see the examples that follow the procedures below.

The procedures below provide high-level outlines for calling a model-defined function as a method on an ObjectContext object and as a static method on a custom class. The examples that follow provide more detail about the steps in the procedures. The procedures assume that you have defined a function in the conceptual model. For more information, see How to: Define Custom Functions in the Conceptual Model.

To call a model-defined function as a method on an ObjectContext object

  1. Add a source file to extend the partial class derived from the ObjectContext class, auto-generated by the Entity Framework tools. Defining the CLR stub in a separate source file will prevent the changes from being lost when the file is regenerated.

  2. Add a common language runtime (CLR) method to your ObjectContext class that does the following:

    • Maps to the function defined in the conceptual model. To map the method, you must apply an EdmFunctionAttribute to the method. Note that the NamespaceName and FunctionName parameters of the attribute are the namespace name of the conceptual model and the function name in the conceptual model, respectively. Function name resolution for LINQ is case sensitive.

    • Returns the results of the Execute method that is returned by the QueryProvider property.

  3. Call the method as a member on an instance of the ObjectContext class.

To call a model-defined function as static method on a custom class

  1. Add a class to your application with a static method that does the following:

    • Maps to the function defined in the conceptual model. To map the method, you must apply an EdmFunctionAttribute to the method. Note that the NamespaceName and FunctionName parameters of the attribute are the namespace name of the conceptual model and the function name in the conceptual model, respectively.

    • Accepts an IQueryable argument.

    • Returns the results of the Execute method that is returned by the Provider property.

  2. Call the method as a member a static method on the custom class

Example

Calling a Model-Defined Function as a Method on an ObjectContext Object

The following example demonstrates how to call a model-defined function as a method on an ObjectContext object. The example uses the AdventureWorks Sales Model.

Consider the conceptual model function below that returns product revenue for a specified product. (For information about adding the function to your conceptual model, see How to: Define Custom Functions in the Conceptual Model.)

XML
<Function Name="GetProductRevenue" ReturnType="Edm.Decimal">
  <Parameter Name="productID" Type="Edm.Int32" />
  <DefiningExpression>
    SUM( SELECT VALUE((s.UnitPrice - s.UnitPriceDiscount)  * s.OrderQty)
    FROM AdventureWorksEntities.SalesOrderDetails as s
    WHERE s.ProductID = productID)
  </DefiningExpression>
</Function>

Example

The following code adds a method to the AdventureWorksEntities class that maps to the conceptual model function above.

C#
public partial class AdventureWorksEntities : ObjectContext
{
    [EdmFunction("AdventureWorksModel", "GetProductRevenue")]
    public decimal? GetProductRevenue(int productId)
    {
        return this.QueryProvider.Execute<decimal?>(Expression.Call(
            Expression.Constant(this),
            (MethodInfo)MethodInfo.GetCurrentMethod(),
            Expression.Constant(productId, typeof(int))));
    }
}

Example

The following code calls the method above to display the product revenue for a specified product:

C#
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    int productId = 776;

    Console.WriteLine(AWEntities.GetProductRevenue(productId));
}

Example

The following example demonstrates how to call a model-defined function that returns a collection (as an IQueryable<T> object). Consider the conceptual model function below that returns all the SalesOrderDetails for a given product ID.

XML
<Function Name="GetDetailsById" 
              ReturnType="Collection(AdventureWorksModel.SalesOrderDetail)">
      <Parameter Name="productID" Type="Edm.Int32" />
      <DefiningExpression>
        SELECT VALUE s
        FROM AdventureWorksEntities.SalesOrderDetails AS s
        WHERE s.ProductID = productID
      </DefiningExpression>
    </Function>

Example

The following code adds a method to the AdventureWorksEntities class that maps to the conceptual model function above.

C#
public partial class AdventureWorksEntities : ObjectContext
{
    [EdmFunction("AdventureWorksModel", "GetDetailsById")]
    public IQueryable<SalesOrderDetail> GetDetailsById(int productId)
    {
        return this.QueryProvider.CreateQuery<SalesOrderDetail>(Expression.Call(
            Expression.Constant(this),
            (MethodInfo)MethodInfo.GetCurrentMethod(),
            Expression.Constant(productId, typeof(int))));
    }
}

Example

The following code calls the method. Note that the returned IQueryable<T> query is further refined to return line totals for each SalesOrderDetail.

C#
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    int productId = 776;

    var lineTotals = AWEntities.GetDetailsById(productId).Select(d =>d.LineTotal);

    foreach(var lineTotal in lineTotals)
    {
        Console.WriteLine(lineTotal);
    }
}

Example

Calling a Model-Defined Function as a Static Method on a Custom Class

The next example demonstrates how to call a model-defined function as a static method on a custom class. The example uses the AdventureWorks Sales Model.

Note

When you call a model-defined function as a static method on a custom class, the model-defined function must accept a collection and return an aggregation of values in the collection.

Consider the conceptual model function below that returns product revenue for a SalesOrderDetail collection. (For information about adding the function to your conceptual model, see How to: Define Custom Functions in the Conceptual Model.).

XML
<Function Name="GetProductRevenue" ReturnType="Edm.Decimal">
  <Parameter Name="details"
             Type="Collection(AdventureWorksModel.SalesOrderDetail)" />
  <DefiningExpression>
    SUM( SELECT VALUE((s.UnitPrice - s.UnitPriceDiscount)  * s.OrderQty)
    FROM details as s)
  </DefiningExpression>
</Function>

Example

The following code adds a class to your application that contains a static method that maps to the conceptual model function above.

C#
public class MyClass
{
    [EdmFunction("AdventureWorksModel", "GetProductRevenue")]
    public static decimal? GetProductRevenue(IQueryable<SalesOrderDetail> details)
    {
        return details.Provider.Execute<decimal?>(Expression.Call(
            (MethodInfo)MethodInfo.GetCurrentMethod(),
            Expression.Constant(details, typeof(IQueryable<SalesOrderDetail>))));
    }
}

Example

The following code calls the method above to display the product revenue for a SalesOrderDetail collection:

C#
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    int productId = 776;

    var details = from s in AWEntities.SalesOrderDetails 
                  where s.ProductID == productId select s;

    Console.WriteLine(MyClass.GetProductRevenue(details));
}

See also

Compiled Queries (LINQ to Entities)

When you have an application that executes structurally similar queries many times in the Entity Framework, you can frequently increase performance by compiling the query one time and executing it several times with different parameters. For example, an application might have to retrieve all the customers in a particular city; the city is specified at runtime by the user in a form. LINQ to Entities supports using compiled queries for this purpose.

Starting with the .NET Framework 4.5, LINQ queries are cached automatically. However, you can still use compiled LINQ queries to reduce this cost in later executions and compiled queries can be more efficient than LINQ queries that are automatically cached. Note that LINQ to Entities queries that apply the Enumerable.Contains operator to in-memory collections are not automatically cached. Also parameterizing in-memory collections in compiled LINQ queries is not allowed.

The CompiledQuery class provides compilation and caching of queries for reuse. Conceptually, this class contains a CompiledQuery's Compile method with several overloads. Call the Compile method to create a new delegate to represent the compiled query. The Compile methods, provided with a ObjectContext and parameter values, return a delegate that produces some result (such as an IQueryable<T> instance). The query compiles once during only the first execution. The merge options set for the query at the time of the compilation cannot be changed later. Once the query is compiled you can only supply parameters of primitive type but you cannot replace parts of the query that would change the generated SQL. For more information, see Entity Framework Merge Options and Compiled Queries

The LINQ to Entities query expression that the CompiledQuery's Compile method compiles is represented by one of the generic Func delegates, such as Func<T1,T2,T3,T4,TResult>. At most, the query expression can encapsulate an ObjectContext parameter, a return parameter, and 16 query parameters. If more than 16 query parameters are required, you can create a structure whose properties represent query parameters. You can then use the properties on the structure in the query expression after you set the properties.

Example

The following example compiles and then invokes a query that accepts a Decimal input parameter and returns a sequence of orders where the total due is greater than or equal to $200.00:

C#
static readonly Func<AdventureWorksEntities, Decimal, IQueryable<SalesOrderHeader>> s_compiledQuery2 = 
    CompiledQuery.Compile<AdventureWorksEntities, Decimal, IQueryable<SalesOrderHeader>>(
            (ctx, total) => from order in ctx.SalesOrderHeaders
                            where order.TotalDue >= total
                            select order);

static void CompiledQuery2()
{            
    using (AdventureWorksEntities context = new AdventureWorksEntities())
    {
        Decimal totalDue = 200.00M;

        IQueryable<SalesOrderHeader> orders = s_compiledQuery2.Invoke(context, totalDue);

        foreach (SalesOrderHeader order in orders)
        {
            Console.WriteLine("ID: {0}  Order date: {1} Total due: {2}",
                order.SalesOrderID,
                order.OrderDate,
                order.TotalDue);
        }
    }            
}

Example

The following example compiles and then invokes a query that returns an ObjectQuery<T> instance:

C#
static readonly Func<AdventureWorksEntities, ObjectQuery<SalesOrderHeader>> s_compiledQuery1 = 
    CompiledQuery.Compile<AdventureWorksEntities, ObjectQuery<SalesOrderHeader>>(
            ctx => ctx.SalesOrderHeaders);

static void CompiledQuery1_MQ()
{
    
    using (AdventureWorksEntities context = new AdventureWorksEntities())
    {
        IQueryable<SalesOrderHeader> orders = s_compiledQuery1.Invoke(context);

        foreach (SalesOrderHeader order in orders)
            Console.WriteLine(order.SalesOrderID);
    }            
}

Example

The following example compiles and then invokes a query that returns the average of the product list prices as a Decimal value:

C#
static readonly Func<AdventureWorksEntities, Decimal> s_compiledQuery3MQ = CompiledQuery.Compile<AdventureWorksEntities, Decimal>(
            ctx => ctx.Products.Average(product => product.ListPrice));

static void CompiledQuery3_MQ()
{
    
    using (AdventureWorksEntities context = new AdventureWorksEntities())
    {
        Decimal averageProductPrice = s_compiledQuery3MQ.Invoke(context);

        Console.WriteLine("The average of the product list prices is $: {0}", averageProductPrice);
    }            
}

Example

The following example compiles and then invokes a query that accepts a String input parameter and then returns a Contact whose email address starts with the specified string:

C#
static readonly Func<AdventureWorksEntities, string, Contact> s_compiledQuery4MQ = 
    CompiledQuery.Compile<AdventureWorksEntities, string, Contact>(
            (ctx, name) => ctx.Contacts.First(contact => contact.EmailAddress.StartsWith(name)));

static void CompiledQuery4_MQ()
{            
    using (AdventureWorksEntities context = new AdventureWorksEntities())
    {
        string contactName = "caroline";
        Contact foundContact = s_compiledQuery4MQ.Invoke(context, contactName);

        Console.WriteLine("An email address starting with 'caroline': {0}",
            foundContact.EmailAddress);
    }            
}

Example

The following example compiles and then invokes a query that accepts DateTime and Decimal input parameters and returns a sequence of orders where the order date is later than March 8, 2003, and the total due is less than $300.00:

C#
static readonly Func<AdventureWorksEntities, DateTime, Decimal, IQueryable<SalesOrderHeader>> s_compiledQuery5 = 
    CompiledQuery.Compile<AdventureWorksEntities, DateTime, Decimal, IQueryable<SalesOrderHeader>>(
            (ctx, orderDate, totalDue) => from product in ctx.SalesOrderHeaders
                                          where product.OrderDate > orderDate 
                                             && product.TotalDue < totalDue
                                          orderby product.OrderDate
                                          select product);

static void CompiledQuery5()
{            
    using (AdventureWorksEntities context = new AdventureWorksEntities())
    {         
        DateTime date = new DateTime(2003, 3, 8);
        Decimal amountDue = 300.00M;

        IQueryable<SalesOrderHeader> orders = s_compiledQuery5.Invoke(context, date, amountDue);

        foreach (SalesOrderHeader order in orders)
        {
            Console.WriteLine("ID: {0} Order date: {1} Total due: {2}", order.SalesOrderID, order.OrderDate, order.TotalDue);
        }
    }            
}

Example

The following example compiles and then invokes a query that accepts a DateTime input parameter and returns a sequence of orders where the order date is later than March 8, 2004. This query returns the order information as a sequence of anonymous types. Anonymous types are inferred by the compiler, so you cannot specify type parameters in the CompiledQuery's Compile method and the type is defined in the query itself.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var compiledQuery = CompiledQuery.Compile((AdventureWorksEntities ctx, DateTime orderDate) =>
        from order in ctx.SalesOrderHeaders
        where order.OrderDate > orderDate
        select new {order.OrderDate, order.SalesOrderID, order.TotalDue});

    DateTime date = new DateTime(2004, 3, 8);
    var results = compiledQuery.Invoke(context, date);

    foreach (var order in results)
    {
        Console.WriteLine("ID: {0} Order date: {1} Total due: {2}", order.SalesOrderID, order.OrderDate, order.TotalDue);
    }
}

Example

The following example compiles and then invokes a query that accepts a user-defined structure input parameter and returns a sequence of orders. The structure defines start date, end date, and total due query parameters, and the query returns orders shipped between March 3 and March 8, 2003 with a total due greater than $700.00.

C#
static Func<AdventureWorksEntities, MyParams, IQueryable<SalesOrderHeader>> s_compiledQuery = 
    CompiledQuery.Compile<AdventureWorksEntities, MyParams, IQueryable<SalesOrderHeader>>(
            (ctx, myparams) => from sale in ctx.SalesOrderHeaders
                               where sale.ShipDate > myparams.startDate && sale.ShipDate < myparams.endDate 
                               && sale.TotalDue > myparams.totalDue  
                               select sale);
static void CompiledQuery7()
{
    
    using (AdventureWorksEntities context = new AdventureWorksEntities())
    {
        MyParams myParams = new MyParams();
        myParams.startDate = new DateTime(2003, 3, 3);
        myParams.endDate = new DateTime(2003, 3, 8);
        myParams.totalDue = 700.00M;

        

        IQueryable<SalesOrderHeader> sales = s_compiledQuery.Invoke(context, myParams);

        foreach (SalesOrderHeader sale in sales)
        {
            Console.WriteLine("ID: {0}", sale.SalesOrderID);
            Console.WriteLine("Ship date: {0}", sale.ShipDate);
            Console.WriteLine("Total due: {0}", sale.TotalDue);
        }
    }            
}

The structure that defines the query parameters:

C#
struct MyParams
{
    public DateTime startDate;
    public DateTime endDate;
    public decimal totalDue;
}

See also

Query Execution

After a LINQ query is created by a user, it is converted to a command tree. A command tree is a representation of a query that is compatible with the Entity Framework. The command tree is then executed against the data source. At query execution time, all query expressions (that is, all components of the query) are evaluated, including those expressions that are used in result materialization.

At what point query expressions are executed can vary. LINQ queries are always executed when the query variable is iterated over, not when the query variable is created. This is called deferred execution. You can also force a query to execute immediately, which is useful for caching query results. This is described later in this topic.

When a LINQ to Entities query is executed, some expressions in the query might be executed on the server and some parts might be executed locally on the client. Client-side evaluation of an expression takes place before the query is executed on the server. If an expression is evaluated on the client, the result of that evaluation is substituted for the expression in the query, and the query is then executed on the server. Because queries are executed on the data source, the data source configuration overrides the behavior specified in the client. For example, null value handling and numerical precision depend on the server settings. Any exceptions thrown during query execution on the server are passed directly up to the client.

Tip

For a convenient summary of query operators in table format, which lets you quickly identify an operator's execution behavior, see Classification of Standard Query Operators by Manner of Execution (C#).

Deferred query execution

In a query that returns a sequence of values, the query variable itself never holds the query results and only stores the query commands. Execution of the query is deferred until the query variable is iterated over in a foreach or For Each loop. This is known as deferred execution; that is, query execution occurs some time after the query is constructed. This means that you can execute a query as frequently as you want to. This is useful when, for example, you have a database that is being updated by other applications. In your application, you can create a query to retrieve the latest information and repeatedly execute the query, returning the updated information every time.

Deferred execution enables multiple queries to be combined or a query to be extended. When a query is extended, it is modified to include the new operations, and the eventual execution will reflect the changes. In the following example, the first query returns all the products. The second query extends the first by using Where to return all the products of size "L":

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<Product> productsQuery =
        from p in context.Products
        select p;

    IQueryable<Product> largeProducts = productsQuery.Where(p => p.Size == "L");

    Console.WriteLine("Products of size 'L':");
    foreach (var product in largeProducts)
    {
        Console.WriteLine(product.Name);
    }
}

After a query has been executed all successive queries will use the in-memory LINQ operators. Iterating over the query variable by using a foreach or For Each statement or by calling one of the LINQ conversion operators will cause immediate execution. These conversion operators include the following: ToList, ToArray, ToLookup, and ToDictionary.

Immediate Query Execution

In contrast to the deferred execution of queries that produce a sequence of values, queries that return a singleton value are executed immediately. Some examples of singleton queries are Average, Count, First, and Max. These execute immediately because the query must produce a sequence to calculate the singleton result. You can also force immediate execution. This is useful when you want to cache the results of a query. To force immediate execution of a query that does not produce a singleton value, you can call the ToList method, the ToDictionary method, or the ToArray method on a query or query variable. The following example uses the ToArray method to immediately evaluate a sequence into an array.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Product> products = context.Products;

    Product[] prodArray = (
        from product in products
        orderby product.ListPrice descending
        select product).ToArray();

    Console.WriteLine("Every price from highest to lowest:");
    foreach (Product product in prodArray)
    {
        Console.WriteLine(product.ListPrice);
    }
}

You could also force execution by putting the foreach or For Each loop immediately after the query expression, but by calling ToList or ToArray you cache all the data in a single collection object.

Store Execution

In general, expressions in LINQ to Entities are evaluated on the server, and the behavior of the expression should not be expected to follow common language runtime (CLR) semantics, but those of the data source. There are exceptions to this, however, such as when the expression is executed on the client. This could cause unexpected results, for example when the server and client are in different time zones.

Some expressions in the query might be executed on the client. In general, most query execution is expected to occur on the server. Aside from methods executed against query elements mapped to the data source, there are often expressions in the query that can be executed locally. Local execution of a query expression yields a value that can be used in the query execution or result construction.

Certain operations are always executed on the client, such as binding of values, sub expressions, sub queries from closures, and materialization of objects into query results. The net effect of this is that these elements (for example, parameter values) cannot be updated during the execution. Anonymous types can be constructed inline on the data source, but should not be assumed to do so. Inline groupings can be constructed in the data source, as well, but this should not be assumed in every instance. In general, it is best not to make any assumptions about what is constructed on the server.

This section describes the scenarios in which code is executed locally on the client. For more information about which types of expressions are executed locally, see Expressions in LINQ to Entities Queries.

Literals and Parameters

Local variables, such as the orderID variable in the following example, are evaluated on the client.

C#
int orderID = 51987;

IQueryable<SalesOrderHeader> salesInfo =
    from s in context.SalesOrderHeaders
    where s.SalesOrderID == orderID
    select s;

Method parameters are also evaluated on the client. The orderID parameter passed into the MethodParameterExample method, below, is an example.

C#
public static void MethodParameterExample(int orderID)
{
    using (AdventureWorksEntities context = new AdventureWorksEntities())
    {
        
        IQueryable<SalesOrderHeader> salesInfo =
            from s in context.SalesOrderHeaders
            where s.SalesOrderID == orderID
            select s;                

        foreach (SalesOrderHeader sale in salesInfo)
        {
            Console.WriteLine("OrderID: {0}, Total due: {1}", sale.SalesOrderID, sale.TotalDue);
        }
    }
}

Casting Literals on the Client

Casting from null to a CLR type is executed on the client:

C#
IQueryable<Contact> query =
    from c in context.Contacts
    where c.EmailAddress == (string)null
    select c;

Casting to a type, such as a nullable Decimal, is executed on the client:

C#
var weight = (decimal?)23.77;
IQueryable<Product> query =
    from product in context.Products
    where product.Weight == weight
    select product;

Constructors for Literals

New CLR types that can be mapped to conceptual model types are executed on the client:

C#
var weight = new decimal(23.77);
IQueryable<Product> query =
    from product in context.Products
    where product.Weight == weight
    select product;

New arrays are also executed on the client.

Store Exceptions

Any store errors that are encountered during query execution are passed up to the client, and are not mapped or handled.

Store Configuration

When the query executes on the store, the store configuration overrides all client behaviors, and store semantics are expressed for all operations and expressions. This can result in a difference in behavior between CLR and store execution in areas such as null comparisons, GUID ordering, precision and accuracy of operations involving non-precise data types (such as floating point types or DateTime), and string operations. It is important to keep this in mind when examining query results.

For example, the following are some differences in behavior between the CLR and SQL Server:

  • SQL Server orders GUIDs differently than the CLR.

  • There can also be differences in result precision when dealing with the Decimal type on SQL Server. This is due to the fixed precision requirements of the SQL Server decimal type. For example, the average of Decimal values 0.0, 0.0, and 1.0 is 0.3333333333333333333333333333 in memory on the client, but 0.333333 in the store (based on the default precision for SQL Server’s decimal type).

  • Some string comparison operations are also handled differently in SQL Server than in the CLR. String comparison behavior depends on the collation settings on the server.

  • Function or method calls, when included in a LINQ to Entities query, are mapped to canonical functions in the Entity Framework, which are then translated to Transact-SQL and executed on the SQL Server database. There are cases when the behavior these mapped functions exhibit might differ from the implementation in the base class libraries. For example, calling the Contains, StartsWith, and EndsWith methods with an empty string as a parameter will return true when executed in the CLR, but will return false when executed in SQL Server. The EndsWith method can also return different results because SQL Server considers two strings to be equal if they only differ in trailing white space, whereas the CLR considers them to be not equal. This is illustrated by the following example:

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<string> query = from p in context.Products
                               where p.Name == "Reflector"
                               select p.Name;

    IEnumerable<bool> q = query.Select(c => c.EndsWith("Reflector "));

    Console.WriteLine("LINQ to Entities returns: " + q.First());
    Console.WriteLine("CLR returns: " + "Reflector".EndsWith("Reflector "));

Query Results

After a LINQ to Entities query is converted to command trees and executed, the query results are usually returned as one of the following:

  • A collection of zero or more typed entity objects or a projection of complex types in the conceptual model.

  • CLR types supported by the conceptual model.

  • Inline collections.

  • Anonymous types.

When the query has executed against the data source, the results are materialized into CLR types and returned to the client. All object materialization is performed by the Entity Framework. 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.

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. However, if the query returns a collection of typed entity objects, represented by ObjectQuery<T>, those types are tracked by the object context. All object behavior (such as child/parent collections, change tracking, polymorphism, and so on) are as defined in the Entity Framework. This functionality can be used in its capacity, as defined in the Entity Framework. For more information, see Working with Objects.

Struct types returned from queries (such as anonymous types and nullable complex types) can be of null value. An EntityCollection<TEntity> property of a returned entity can also be of null value. 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.

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.

The following example contains a custom class, MyContact, with a LastName property. When the LastName property is set, a count variable is incremented. If you execute the two following queries, the first query will increment count while the second query will not. 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.

C#
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();
}
C#
public class MyContact
{

    String _lastName;

    public string LastName
    {
        get
        {
            return _lastName;
        }

        set
        {
            _lastName = value;
            count++;
        }
    }
}

Standard Query Operators in LINQ to Entities Queries

In a query, you specify the information that you want to retrieve from the data source. A query can also specify how that information should be sorted, grouped, and shaped before it is returned. LINQ provides a set of standard query methods that you can use in a query. Most of these methods operate on sequences; in this context, a sequence is an object whose type implements the IEnumerable<T> interface or the IQueryable<T> interface. The standard query operators query functionality includes filtering, projection, aggregation, sorting, grouping, paging, and more. Some of the more frequently used standard query operators have dedicated keyword syntax so that they can be called by using query expression syntax. A query expression is a different, more readable way to express a query than the method-based equivalent. Query expression clauses are translated into calls to the query methods at compile time. For a list of standard query operators that have equivalent query expression clauses, see Standard Query Operators Overview.

Not all of the standard query operators are supported in LINQ to Entities queries. For more information, see Supported and Unsupported LINQ Methods (LINQ to Entities). This topic provides information about the standard query operators that is specific to LINQ to Entities. For more information about known issues in LINQ to Entities queries, see Known Issues and Considerations in LINQ to Entities.

Projection and Filtering Methods

Projection refers to transforming the elements of a result set into a desired form. For example, you can project a subset of the properties you need from each object in the result set, you can project a property and perform a mathematical calculation on it, or you can project the entire object from the result set. The projection methods are Select and SelectMany.

Filtering refers to the operation of restricting the result set to contain only those elements that match a specified condition. The filtering method is Where.

Most overloads of the projection and filtering methods are supported in LINQ to Entities, with the exception of those that accept a positional argument.

Join Methods

Joining is an important operation in queries that target data sources that have no navigable relationships to each other. A join of two data sources is the association of objects in one data source with objects in the other data source that share a common attribute or property. The join methods are Join and GroupJoin.

Most overloads of the join methods are supported, with the exception of those that use a IEqualityComparer<T>. This is because the comparer cannot be translated to the data source.

Set Methods

Set operations in LINQ are query operations that base their result sets on the presence or absence of equivalent elements within the same or in another collection (or set). The set methods are All, Any, Concat, Contains, DefaultIfEmpty, Distinct, EqualAll, Except, Intersect, and Union.

Most overloads of the set methods are supported in LINQ to Entities, though there are some differences in behavior compared to LINQ to Objects. However, set methods that use an IEqualityComparer<T> are not supported because the comparer cannot be translated to the data source.

Ordering Methods

Ordering, or sorting, refers to the ordering the elements of a result set based on one or more attributes. By specifying more than one sort criterion, you can break ties within a group.

Most overloads of the ordering methods are supported, with the exception of those that use an IComparer<T>. This is because the comparer cannot be translated to the data source. The ordering methods are OrderBy, OrderByDescending, ThenBy, ThenByDescending, and Reverse.

Because the query is executed on the data source, the ordering behavior may differ from queries executed in the CLR. This is because ordering options, such as case ordering, kanji ordering, and null ordering, can be set in the data source. Depending on the data source, these ordering options might produce different results than in the CLR.

If you specify the same key selector in more than one ordering operation, a duplicate ordering will be produced. This is not valid and an exception will be thrown.

Grouping Methods

Grouping refers to placing data into groups so that the elements in each group share a common attribute. The grouping method is GroupBy.

Most overloads of the grouping methods are supported, with the exception of those that use an IEqualityComparer<T>. This is because the comparer cannot be translated to the data source.

The grouping methods are mapped to the data source using a distinct sub-query for the key selector. The key selector comparison sub-query is executed by using the semantics of the data source, including issues related to comparing null values.

Aggregate Methods

An aggregation operation computes a single value from a collection of values. For example, calculating the average daily temperature from a month's worth of daily temperature values is an aggregation operation. The aggregate methods are Aggregate, Average, Count, LongCount, Max, Min, and Sum.

Most overloads of the aggregate methods are supported. For behavior related to null values, the aggregate methods use the data source semantics. The behavior of the aggregation methods when null values are involved might be different, depending on which back-end data source is being used. Aggregate method behavior using the semantics of the data source might also be different from what is expected from CLR methods. For example, the default behavior for the Sum method on SQL Server is to ignore any null values instead of throwing an exception.

Any exceptions that result from aggregation, such as an overflow from the Sum function, are thrown as data source exceptions or Entity Framework exceptions during the materialization of the query results.

For those methods that involve a calculation over a sequence, such as Sum or Average, the actual calculation is performed on the server. As a result, type conversions and loss of precision might occur on the server, and the results might differ from what is expected using CLR semantics.

The default behavior of the aggregate methods for null/non-null values is shown in the following table:

Method No data All null values Some null values No null values
Average Returns null. Returns null. Returns the average of the non-null values in a sequence. Computes the average of a sequence of numeric values.
Count Returns 0 Returns the number of null values in the sequence. Returns the number of null and non-null values in the sequence. Returns the number of elements in the sequence.
Max Returns null. Returns null. Returns the maximum non-null value in a sequence. Returns the maximum value in a sequence.
Min Returns null. Returns null. Returns the minimum non-null value in a sequence. Returns the minimum value in a sequence.
Sum Returns null. Returns null. Returns the sum of the non-null value in a sequence. Computes the sum of a sequence of numeric values.

Type Methods

The two LINQ methods that deal with type conversion and testing are both supported in the context of the Entity Framework. This means that the only supported types are types that map to the appropriate Entity Framework type. For a list of these types, see Conceptual Model Types (CSDL). The type methods are Convert and OfType.

OfType is supported for entity types. Convert is supported for conceptual model primitive types. The C# is and as methods are also supported.

Paging Methods

Paging operations return a single element or multiple elements from a sequence. The supported paging methods are First, FirstOrDefault, Single, SingleOrDefault, Skip, and Take.

A number of paging methods are not supported, due either to the inability to map functions to the data source or to the lack of implicit ordering of sets on the data source. Methods that return a default value are restricted to conceptual model primitive types and reference types with null defaults. Paging methods that are executed on an empty sequence will return null.

See also

CLR Method to Canonical Function Mapping

The Entity Framework provides a set of canonical functions that implement functionality that is common across many database systems, such as string manipulation and mathematical functions. This enables developers to target a broad range of database systems. When called from a querying technology, such as LINQ to Entities, these canonical functions are translated to the correct corresponding store function for the provider being used. This allows function invocations to be expressed in a common form across data sources, providing a consistent query experience across data sources. The bitwise AND, OR, NOT, and XOR operators are also mapped to canonical functions when the operand is a numeric type. For Boolean operands, the bitwise AND, OR, NOT, and XOR operators compute the logical AND, OR, NOT, and XOR operations of their operands. For more information, see Canonical Functions.

For LINQ scenarios, queries against the Entity Framework involve mapping certain CLR methods to methods on the underlying data source through canonical functions. Any method calls in a LINQ to Entities query that are not explicitly mapped to a canonical function will result in a runtime NotSupportedException exception being thrown.

System.String Method (Static) Mapping

System.String method (static) Canonical function
System.String Concat(String str0, String str1) Concat(str0, str1)
System.String Concat(String str0, String str1, String str2) Concat(Concat(str0, str1), str2)
System.String Concat(String str0, String str1, String str2, String str03) Concat(Concat(Concat(str0, str1), str2), str3)
Boolean Equals(String a, String b) = operator
Boolean IsNullOrEmpty(String value) (IsNull(value)) OR Length(value) = 0
Boolean op_Equality(String a, String b) = operator
Boolean op_Inequality(String a , String b) != operator
Microsoft.VisualBasic.Strings.Trim(String str) Trim(str)
Microsoft.VisualBasic.Strings.LTrim(String str) Ltrim(str)
Microsoft.VisualBasic.Strings.RTrim(String str) Rtrim(str)
Microsoft.VisualBasic.Strings.Len(String expression) Length(expression)
Microsoft.VisualBasic.Strings.Left(String str, Int32 Length) Left(str, Length)
Microsoft.VisualBasic.Strings.Mid(String str, Int32 Start, Int32 Length) Substring(str, Start, Length)
Microsoft.VisualBasic.Strings.Right(String str, Int32 Length) Right(str, Length)
Microsoft.VisualBasic.Strings.UCase(String Value) ToUpper(Value)
Microsoft.VisualBasic.Strings.LCase(String Value) ToLower(Value)

System.String Method (Instance) Mapping

System.String method (instance) Canonical function Notes
Boolean Contains(String value) this LIKE '%value%' If value is not a constant, then this maps to IndexOf(this, value) > 0
Boolean EndsWith(String value) this LIKE '%value' If value is not a constant, then this maps to Right(this, length(value)) = value.
Boolean StartsWith(String value) this LIKE 'value%' If value is not a constant, then this maps to IndexOf(this, value) = 1.
Length Length(this)
Int32 IndexOf(String value) IndexOf(this, value) - 1
System.String Insert(Int32 startIndex, String value) Concat(Concat(Substring(this, 1, startIndex), value), Substring(this, startIndex+1, Length(this) - startIndex))
System.String Remove(Int32 startIndex) Substring(this, 1, startIndex)
System.String Remove(Int32 startIndex, Int32 count) Concat(Substring(this, 1, startIndex) , Substring(this, startIndex + count +1, Length(this) - (startIndex + count))) Remove(startIndex, count) is only supported if count is an integer greater than or equal to 0.
System.String Replace(String oldValue, String newValue) Replace(this, oldValue, newValue)
System.String Substring(Int32 startIndex) Substring(this, startIndex +1, Length(this) - startIndex)
System.String Substring(Int32 startIndex, Int32 length) Substring(this, startIndex +1, length)
System.String ToLower() ToLower(this)
System.String ToUpper() ToUpper(this)
System.String Trim() Trim(this)
System.String TrimEnd(Char[] trimChars) RTrim(this)
System.String TrimStart(Char[]trimChars) LTrim(this)
Boolean Equals(String value) = operator

System.DateTime Method (Static) Mapping

System.DateTime method (static) Canonical function Notes
Boolean Equals(DateTime t1, DateTime t2) = operator
System.DateTime.Now CurrentDateTime()
System.DateTime.UtcNow CurrentUtcDateTime()
Boolean op_Equality(DateTime d1, DateTime d2) = operator
Boolean op_GreaterThan(DateTime t1, DateTime t2) > operator
Boolean op_GreaterThanOrEqual(DateTime t1, DateTime t2) >= operator
Boolean op_Inequality(DateTime t1, DateTime t2) != operator
Boolean op_LessThan(DateTime t1, DateTime t2) < operator
Boolean op_LessThanOrEqual(DateTime t1, DateTime t2) <= operator
Microsoft.VisualBasic.DateAndTime.DatePart( _

ByVal Interval As DateInterval, _

ByVal DateValue As DateTime, _

Optional ByVal FirstDayOfWeekValue As FirstDayOfWeek = VbSunday, _

Optional ByVal FirstWeekOfYearValue As FirstWeekOfYear = VbFirstJan1 _

) As Integer
See the DatePart Function section for more information.
Microsoft.VisualBasic.DateAndTime.Now CurrentDateTime()
Microsoft.VisualBasic.DateAndTime.Year(DateTime TimeValue) Year()
Microsoft.VisualBasic.DateAndTime.Month(DateTime TimeValue) Month()
Microsoft.VisualBasic.DateAndTime.Day(DateTime TimeValue) Day()
Microsoft.VisualBasic.DateAndTime.Hour(DateTime TimeValue) Hour()
Microsoft.VisualBasic.DateAndTime.Minute(DateTime TimeValue) Minute()
Microsoft.VisualBasic.DateAndTime.Second(DateTime TimeValue) Second()

System.DateTime Method (Instance) Mapping

System.DateTime method (instance) Canonical function
Boolean Equals(DateTime value) = operator
Day Day(this)
Hour Hour(this)
Millisecond Millisecond(this)
Minute Minute(this)
Month Month(this)
Second Second(this)
Year Year(this)

System.DateTimeOffset Method (Instance) Mapping

The mapping shown for the get methods on the listed properties.

System.DateTimeOffset method (instance) Canonical function Notes
Day Day(this) Not supported against SQL Server 2005.
Hour Hour(this) Not supported against SQL Server 2005.
Millisecond Millisecond(this) Not supported against SQL Server 2005.
Minute Minute(this) Not supported against SQL Server 2005.
Month Month(this) Not supported against SQL Server 2005.
Second Second(this) Not supported against SQL Server 2005.
Year Year(this) Not supported against SQL Server 2005.

Note

The Equals method returns true if the compared DateTimeOffset objects are equal; false otherwise. The CompareTo method returns 0, 1, or -1 depending on whether the compared DateTimeOffset object is equal, greater than, or less than, respectively.

System.DateTimeOffset Method (Static) Mapping

The mapping shown for the get methods on the listed properties.

System.DateTimeOffset method (static) Canonical function Notes
System.DateTimeOffset.Now() CurrentDateTimeOffset() Not supported against SQL Server 2005.

System.TimeSpan Method (Instance) Mapping

The mapping shown for the get methods on the listed properties.

System.TimeSpan method (instance) Canonical function Notes
Hours Hour(this) Not supported against SQL Server 2005.
Milliseconds Millisecond(this) Not supported against SQL Server 2005.
Minutes Minute(this) Not supported against SQL Server 2005.
Seconds Second(this) Not supported against SQL Server 2005.

Note

The Equals method returns true if the compared TimeSpan objects are equal; false otherwise. The CompareTo method returns 0, 1, or -1 depending on whether the compared TimeSpan object is equal, greater than, or less than, respectively.

DatePart Function

The DatePart Function is mapped to one of several different canonical functions, depending on the value of Interval. The following table displays the canonical function mapping for the supported values of Interval:

Interval value Canonical function
DateInterval.Year Year()
DateInterval.Month Month()
DateInterval.Day Day()
DateInterval.Hour Hour()
DateInterval.Minute Minute()
DateInterval.Second Second()

Mathematical Function Mapping

CLR method Canonical function
System.Decimal.Ceiling(Decimal d) Ceiling(d)
System.Decimal.Floor(Decimal d) Floor(d)
System.Decimal.Round(Decimal d) Round(d)
System.Math.Ceiling(Decimal d) Ceiling(d)
System.Math.Floor(Decimal d) Floor(d)
System.Math.Round(Decimal d) Round(d)
System.Math.Ceiling(Double a) Ceiling(a)
System.Math.Floor(Double a) Floor(a)
System.Math.Round(Double a) Round(a)
System.Math.Round(Double value, Int16 digits) Round(value, digits)
System.Math.Round(Double value, Int32 digits) Round(value, digits)
System.Math.Round(Decimal value, Int16 digits) Round(value, digits)
System.Math.Round(Decimal value, Int32, digits) Round(value, digits)
System.Math.Abs(Int16 value) Abs(value)
System.Math.Abs(Int32 value) Abs(value)
System.Math.Abs(Int64 value) Abs(value)
System.Math.Abs(Byte value) Abs(value)
System.Math.Abs(Single value) Abs(value)
System.Math.Abs(Double value) Abs(value)
System.Math.Abs(Decimal value) Abs(value)
System.Math.Truncate(Double value, Int16 digits) Truncate(value, digits)
System.Math.Truncate(Double value, Int32 digits) Truncate(value, digits)
System.Math.Truncate(Decimal value, Int16 digits) Truncate(value, digits)
System.Math.Truncate(Decimal value, Int32 digits) Truncate(value, digits)
System.Math.Power(Int32 value, Int64 exponent) Power(value, exponent)
System.Math.Power(Int32 value, Double exponent) Power(value, exponent)
System.Math.Power(Int32 value, Decimal exponent) Power(value, exponent)
System.Math.Power(Int64 value, Int64 exponent) Power(value, exponent)
System.Math.Power(Int64 value, Double exponent) Power(value, exponent)
System.Math.Power(Int64 value, Decimal exponent) Power(value, exponent)
System.Math.Power(Double value, Int64 exponent) Power(value, exponent)
System.Math.Power(Double value, Double exponent) Power(value, exponent)
System.Math.Power(Double value, Decimal exponent) Power(value, exponent)
System.Math.Power(Decimal value, Int64 exponent) Power(value, exponent)
System.Math.Power(Decimal value, Double exponent) Power(value, exponent)
System.Math.Power(Decimal value, Decimal exponent) Power(value, exponent)

Bitwise Operator Mapping

Bitwise operator Canonical function for non-Boolean operands Canonical function for Boolean operands
Bitwise AND operator BitWiseAnd op1 AND op2
Bitwise OR operator BitWiseOr op1 OR op2
Bitwise NOT operator BitWiseNot NOT(op)
Bitwise XOR operator BitWiseXor ((op1 AND NOT(op2)) OR (NOT(op1) AND op2))

Other Mapping

Method Canonical function
Guid.NewGuid() NewGuid()

See also

Supported and Unsupported LINQ Methods

This section provides information about the Language-Integrated Query (LINQ) standard query operators that are supported or unsupported in LINQ to Entities queries. Many of the LINQ standard query operators have an overloaded version that accepts an integer argument. The integer argument corresponds to a zero-based index in the sequence that is being operated on, an IEqualityComparer<T>, or IComparer<T>. Unless otherwise specified, these overloaded versions of the LINQ standard query operators are not supported, and attempting to use them will throw an exception.

Projection and Restriction Methods

Most of the LINQ projection and restriction methods are supported in LINQ to Entities queries, with the exception of those that accept a positional argument. For more information, see Standard Query Operators in LINQ to Entities Queries. The following table lists the supported and unsupported projection and restriction methods.

Method Support Visual Basic function signature C# method signature
Select Supported Function Select(Of TSource, TResult) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, TResult)) _ ) As IQueryable(Of TResult) IQueryable<TResult> Select<TSource, TResult>( this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector )
Select Not supported Function Select(Of TSource, TResult) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Integer, TResult)) _ ) As IQueryable(Of TResult) IQueryable<TResult> Select<TSource, TResult>( this IQueryable<TSource> source, Expression<Func<TSource, int, TResult>> selector )
SelectMany Supported Function SelectMany(Of TSource, TResult) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, IEnumerable(Of TResult))) _ ) As IQueryable(Of TResult) IQueryable<TResult> SelectMany<TSource, TResult>( this IQueryable<TSource> source, Expression<Func<TSource, IEnumerable<TResult>>> selector )
SelectMany Not supported Function SelectMany(Of TSource, TResult) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Integer, IEnumerable(Of TResult))) _ ) As IQueryable(Of TResult) IQueryable<TResult> SelectMany<TSource, TResult>( this IQueryable<TSource> source, Expression<Func<TSource, int, IEnumerable<TResult>>> selector )
SelectMany Supported Function SelectMany(Of TSource, TCollection, TResult) ( _ source As IQueryable(Of TSource), _ collectionSelector As Expression(Of Func(Of TSource, IEnumerable(Of TCollection))), _ resultSelector As Expression(Of Func(Of TSource, TCollection, TResult)) _ ) As IQueryable(Of TResult) IQueryable<TResult> SelectMany\<TSource, TCollection, TResult>( this IQueryable<TSource> source, Expression<Func<TSource, IEnumerable<TCollection>>> collectionSelector, Expression<Func\<TSource, TCollection, TResult>> resultSelector )
SelectMany Not supported Function SelectMany(Of TSource, TCollection, TResult) ( _ source As IQueryable(Of TSource), _ collectionSelector As Expression(Of Func(Of TSource, Integer, IEnumerable(Of TCollection))), _ resultSelector As Expression(Of Func(Of TSource, TCollection, TResult)) _ ) As IQueryable(Of TResult) IQueryable<TResult> SelectMany\<TSource, TCollection, TResult>( this IQueryable<TSource> source, Expression<Func<TSource, int, IEnumerable<TCollection>>> collectionSelector, Expression<Func\<TSource, TCollection, TResult>> resultSelector )
Where Supported Function Where(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Boolean)) _ ) As IQueryable(Of TSource) IQueryable<TSource> Where<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, bool>> predicate )
Where Not supported Function Where(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Integer, Boolean)) _ ) As IQueryable(Of TSource) IQueryable<TSource> Where<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, int, bool>> predicate )

Join Methods

The LINQ join methods are supported in LINQ to Entities, with the exception of those that accept an IEqualityComparer because the comparer cannot be translated to the data source. For more information, see Standard Query Operators in LINQ to Entities Queries. The following table lists the supported and unsupported join methods.

Method Support Visual Basic function signature C# method signature
GroupJoin Supported Function GroupJoin(Of TOuter, TInner, TKey, TResult) ( _ outer As IQueryable(Of TOuter), _ inner As IEnumerable(Of TInner), _ outerKeySelector As Expression(Of Func(Of TOuter, TKey)), _ innerKeySelector As Expression(Of Func(Of TInner, TKey)), _ resultSelector As Expression(Of Func(Of TOuter, IEnumerable(Of TInner), TResult)) _ ) As IQueryable(Of TResult) IQueryable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>( this IQueryable<TOuter> outer, IEnumerable<TInner> inner, Expression<Func<TOuter, TKey>> outerKeySelector, Expression<Func<TInner, TKey>> innerKeySelector, Expression<Func<TOuter, IEnumerable<TInner>, TResult>> resultSelector )
GroupJoin Not Supported Function GroupJoin(Of TOuter, TInner, TKey, TResult) ( _ outer As IQueryable(Of TOuter), _ inner As IEnumerable(Of TInner), _ outerKeySelector As Expression(Of Func(Of TOuter, TKey)), _ innerKeySelector As Expression(Of Func(Of TInner, TKey)), _ resultSelector As Expression(Of Func(Of TOuter, IEnumerable(Of TInner), TResult)), _ comparer As IEqualityComparer(Of TKey) _ ) As IQueryable(Of TResult) IQueryable<TResult> GroupJoin\<TOuter, TInner, TKey, TResult>( this IQueryable<TOuter> outer, IEnumerable<TInner> inner, Expression<Func\<TOuter, TKey>> outerKeySelector, Expression<Func\<TInner, TKey>> innerKeySelector, Expression<Func<TOuter, IEnumerable<TInner>, TResult>> resultSelector, IEqualityComparer<TKey> comparer )
Join Supported Function Join(Of TOuter, TInner, TKey, TResult) ( _ outer As IQueryable(Of TOuter), _ inner As IEnumerable(Of TInner), _ outerKeySelector As Expression(Of Func(Of TOuter, TKey)), _ innerKeySelector As Expression(Of Func(Of TInner, TKey)), _ resultSelector As Expression(Of Func(Of TOuter, TInner, TResult)) _ ) As IQueryable(Of TResult) IQueryable<TResult> Join<TOuter, TInner, TKey, TResult>( this IQueryable<TOuter> outer, IEnumerable<TInner> inner, Expression<Func<TOuter, TKey>> outerKeySelector, Expression<Func<TInner, TKey>> innerKeySelector, Expression<Func<TOuter, TInner, TResult>> resultSelector )
Join Not Supported Function Join(Of TOuter, TInner, TKey, TResult) ( _ outer As IQueryable(Of TOuter), _ inner As IEnumerable(Of TInner), _ outerKeySelector As Expression(Of Func(Of TOuter, TKey)), _ innerKeySelector As Expression(Of Func(Of TInner, TKey)), _ resultSelector As Expression(Of Func(Of TOuter, TInner, TResult)), _ comparer As IEqualityComparer(Of TKey) _ ) As IQueryable(Of TResult) IQueryable<TResult> Join\<TOuter, TInner, TKey, TResult>( this IQueryable<TOuter> outer, IEnumerable<TInner> inner, Expression<Func\<TOuter, TKey>> outerKeySelector, Expression<Func\<TInner, TKey>> innerKeySelector, Expression<Func\<TOuter, TInner, TResult>> resultSelector, IEqualityComparer<TKey> comparer )

Set Methods

Most of the LINQ set methods are supported in LINQ to Entities queries, with the exception of those that use an EqualityComparer<T>. For more information, see Standard Query Operators in LINQ to Entities Queries. The following table lists the supported and unsupported set methods.

Method Support Visual Basic function signature C# method signature
All Supported Function All(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Boolean)) _ ) As Boolean bool All<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, bool>> predicate )
Any Supported Function Any(Of TSource) ( _ source As IQueryable(Of TSource) _ ) As Boolean bool Any<TSource>( this IQueryable<TSource> source )
Any Supported Function Any(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Boolean)) _ ) As Boolean bool Any<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, bool>> predicate )
Contains Supported Function Contains(Of TSource) ( _ source As IQueryable(Of TSource), _ item As TSource _ ) As Boolean bool Contains<TSource>( this IQueryable<TSource> source, TSource item )
Contains Not supported Function Contains(Of TSource) ( _ source As IQueryable(Of TSource), _ item As TSource, _ comparer As IEqualityComparer(Of TSource) _ ) As Boolean bool Contains<TSource>( this IQueryable<TSource> source, TSource item, IEqualityComparer<TSource> comparer )
Concat Supported, but there is no

guarantee of order being preserved
Function Concat(Of TSource) ( _ source1 As IQueryable(Of TSource), _ source2 As IEnumerable(Of TSource) _ ) As IQueryable(Of TSource) IQueryable<TSource> Concat<TSource>( this IQueryable<TSource> source1, IEnumerable<TSource> source2 )
DefaultIfEmpty Supported Function DefaultIfEmpty(Of TSource) ( _ source As IQueryable(Of TSource) _ ) As IQueryable(Of TSource) IQueryable<TSource> DefaultIfEmpty<TSource>( this IQueryable<TSource> source )
DefaultIfEmpty Supported Function DefaultIfEmpty(Of TSource) ( _ source As IQueryable(Of TSource), _ defaultValue As TSource _ ) As IQueryable(Of TSource) IQueryable<TSource> DefaultIfEmpty<TSource>( this IQueryable<TSource> source, TSource defaultValue )
Distinct Supported Function Distinct(Of TSource) ( _ source As IQueryable(Of TSource) _ ) As IQueryable(Of TSource) IQueryable<TSource> Distinct<TSource>( this IQueryable<TSource> source )
Distinct Not supported Function Distinct(Of TSource) ( _ source As IQueryable(Of TSource), _ comparer As IEqualityComparer(Of TSource) _ ) As IQueryable(Of TSource) IQueryable<TSource> Distinct<TSource>( this IQueryable<TSource> source, IEqualityComparer<TSource> comparer )
Except Supported Function Except(Of TSource) ( _ source1 As IQueryable(Of TSource), _ source2 As IEnumerable(Of TSource) _ ) As IQueryable(Of TSource) IQueryable<TSource> Except<TSource>( this IQueryable<TSource> source1, IEnumerable<TSource> source2 )
Except Not supported Function Except(Of TSource) ( _ source1 As IQueryable(Of TSource), _ source2 As IEnumerable(Of TSource), _ comparer As IEqualityComparer(Of TSource) _ ) As IQueryable(Of TSource) IQueryable<TSource> Except<TSource>( this IQueryable<TSource> source1, IEnumerable<TSource> source2, IEqualityComparer<TSource> comparer )
Intersect Supported Function Intersect(Of TSource) ( _ source1 As IQueryable(Of TSource), _ source2 As IEnumerable(Of TSource) _ ) As IQueryable(Of TSource) IQueryable<TSource> Intersect<TSource>( this IQueryable<TSource> source1, IEnumerable<TSource> source2 )
Intersect Not supported Function Intersect(Of TSource) ( _ source1 As IQueryable(Of TSource), _ source2 As IEnumerable(Of TSource), _ comparer As IEqualityComparer(Of TSource) _ ) As IQueryable(Of TSource) IQueryable<TSource> Intersect<TSource>( this IQueryable<TSource> source1, IEnumerable<TSource> source2, IEqualityComparer<TSource> comparer )
Union Supported Function Union(Of TSource) ( _ source1 As IQueryable(Of TSource), _ source2 As IEnumerable(Of TSource) _ ) As IQueryable(Of TSource) IQueryable<TSource> Union<TSource>( this IQueryable<TSource> source1, IEnumerable<TSource> source2 )
Union Not supported Function Union(Of TSource) ( _ source1 As IQueryable(Of TSource), _ source2 As IEnumerable(Of TSource), _ comparer As IEqualityComparer(Of TSource) _ ) As IQueryable(Of TSource) IQueryable<TSource> Union<TSource>( this IQueryable<TSource> source1, IEnumerable<TSource> source2, IEqualityComparer<TSource> comparer )

Ordering Methods

Most of the LINQ ordering methods are supported in LINQ to Entities, with the exception of those that accept an IComparer<T>, because the comparer cannot be translated to the data source. For more information, see Standard Query Operators in LINQ to Entities Queries. The following table lists the supported and unsupported ordering methods.

Method Support Visual Basic function signature C# method signature
OrderBy Supported Function OrderBy(Of TSource, TKey) ( _ source As IQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)) _ ) As IOrderedQueryable(Of TSource) IOrderedQueryable<TSource> OrderBy<TSource, TKey>( this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector )
OrderBy Not supported Function OrderBy(Of TSource, TKey) ( _ source As IQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)), _ comparer As IComparer(Of TKey) _ ) As IOrderedQueryable(Of TSource) IOrderedQueryable<TSource> OrderBy\<TSource, TKey>( this IQueryable<TSource> source, Expression<Func\<TSource, TKey>> keySelector, IComparer<TKey> comparer )
OrderByDescending Supported Function OrderByDescending(Of TSource, TKey) ( _ source As IQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)) _ ) As IOrderedQueryable(Of TSource) IOrderedQueryable<TSource> OrderByDescending<TSource, TKey>( this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector )
OrderByDescending Not supported Function OrderByDescending(Of TSource, TKey) ( _ source As IQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)), _ comparer As IComparer(Of TKey) _ ) As IOrderedQueryable(Of TSource) IOrderedQueryable<TSource> OrderByDescending\<TSource, TKey>( this IQueryable<TSource> source, Expression<Func\<TSource, TKey>> keySelector, IComparer<TKey> comparer )
ThenBy Supported Function ThenBy(Of TSource, TKey) ( _ source As IOrderedQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)) _ ) As IOrderedQueryable(Of TSource) IOrderedQueryable<TSource> ThenBy<TSource, TKey>( this IOrderedQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector )
ThenBy Not supported Function ThenBy(Of TSource, TKey) ( _ source As IOrderedQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)), _ comparer As IComparer(Of TKey) _ ) As IOrderedQueryable(Of TSource) IOrderedQueryable<TSource> ThenBy\<TSource, TKey>( this IOrderedQueryable<TSource> source, Expression<Func\<TSource, TKey>> keySelector, IComparer<TKey> comparer )
ThenByDescending Supported Function ThenByDescending(Of TSource, TKey) ( _ source As IOrderedQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)) _ ) As IOrderedQueryable(Of TSource) IOrderedQueryable<TSource> ThenByDescending<TSource, TKey>( this IOrderedQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector )
ThenByDescending Not supported Function ThenByDescending(Of TSource, TKey) ( _ source As IOrderedQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)), _ comparer As IComparer(Of TKey) _ ) As IOrderedQueryable(Of TSource) IOrderedQueryable<TSource> ThenByDescending\<TSource, TKey>( this IOrderedQueryable<TSource> source, Expression<Func\<TSource, TKey>> keySelector, IComparer<TKey> comparer )
Reverse Not supported Function Reverse(Of TSource) ( _ source As IQueryable(Of TSource) _ ) As IQueryable(Of TSource) IQueryable<TSource> Reverse<TSource>( this IQueryable<TSource> source )

Grouping Methods

Most of the LINQ grouping methods are supported in LINQ to Entities, with the exception of those that accept an IEqualityComparer<T>, because the comparer cannot be translated to the data source. For more information, see Standard Query Operators in LINQ to Entities Queries. The following table lists the supported and unsupported grouping methods.

Method Support Visual Basic function signature C# method signature
GroupBy Supported Function GroupBy(Of TSource, TKey) ( _ source As IQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)) _ ) As IQueryable(Of IGrouping(Of TKey, TSource)) IQueryable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>( this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector )
GroupBy Not supported Function GroupBy(Of TSource, TKey) ( _ source As IQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)), _ comparer As IEqualityComparer(Of TKey) _ ) As IQueryable(Of IGrouping(Of TKey, TSource)) IQueryable<IGrouping\<TKey, TSource>> GroupBy\<TSource, TKey>( this IQueryable<TSource> source, Expression<Func\<TSource, TKey>> keySelector, IEqualityComparer<TKey> comparer )
GroupBy Supported Function GroupBy(Of TSource, TKey, TElement) ( _ source As IQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)), _ elementSelector As Expression(Of Func(Of TSource, TElement)) _ ) As IQueryable(Of IGrouping(Of TKey, TElement)) IQueryable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>( this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, Expression<Func<TSource, TElement>> elementSelector )
GroupBy Supported Function GroupBy(Of TSource, TKey, TResult) ( _ source As IQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)), _ resultSelector As Expression(Of Func(Of TKey, IEnumerable(Of TSource), TResult)) _ ) As IQueryable(Of TResult) IQueryable<TResult> GroupBy\<TSource, TKey, TResult>( this IQueryable<TSource> source, Expression<Func\<TSource, TKey>> keySelector, Expression<Func<TKey, IEnumerable<TSource>, TResult>> resultSelector )
GroupBy Not supported Function GroupBy(Of TSource, TKey, TElement) ( _ source As IQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)), _ elementSelector As Expression(Of Func(Of TSource, TElement)), _ comparer As IEqualityComparer(Of TKey) _ ) As IQueryable(Of IGrouping(Of TKey, TElement)) IQueryable<IGrouping\<TKey, TElement>> GroupBy\<TSource, TKey, TElement>( this IQueryable<TSource> source, Expression<Func\<TSource, TKey>> keySelector, Expression<Func\<TSource, TElement>> elementSelector, IEqualityComparer<TKey> comparer
GroupBy Supported Function GroupBy(Of TSource, TKey, TElement, TResult) ( _ source As IQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)), _ elementSelector As Expression(Of Func(Of TSource, TElement)), _ resultSelector As Expression(Of Func(Of TKey, IEnumerable(Of TElement), TResult)) _ ) As IQueryable(Of TResult) IQueryable<TResult> GroupBy<TSource, TKey, TElement, TResult>( this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, Expression<Func<TSource, TElement>> elementSelector, Expression<Func<TKey, IEnumerable<TElement>, TResult>> resultSelector )
GroupBy Not supported Function GroupBy(Of TSource, TKey, TResult) ( _ source As IQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)), _ resultSelector As Expression(Of Func(Of TKey, IEnumerable(Of TSource), TResult)), _ comparer As IEqualityComparer(Of TKey) _ ) As IQueryable(Of TResult) IQueryable<TResult> GroupBy\<TSource, TKey, TResult>( this IQueryable<TSource> source, Expression<Func\<TSource, TKey>> keySelector, Expression<Func<TKey, IEnumerable<TSource>, TResult>> resultSelector, IEqualityComparer<TKey> comparer )
GroupBy Not supported Function GroupBy(Of TSource, TKey, TElement, TResult) ( _ source As IQueryable(Of TSource), _ keySelector As Expression(Of Func(Of TSource, TKey)), _ elementSelector As Expression(Of Func(Of TSource, TElement)), _ resultSelector As Expression(Of Func(Of TKey, IEnumerable(Of TElement), TResult)), _ comparer As IEqualityComparer(Of TKey) _ ) As IQueryable(Of TResult) IQueryable<TResult> GroupBy<TSource, TKey, TElement, TResult>( this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, Expression<Func<TSource, TElement>> elementSelector, Expression<Func<TKey, IEnumerable<TElement>, TResult>> resultSelector, IEqualityComparer<TKey> comparer )

Aggregate Methods

Most of the aggregate methods that accept primitive data types are supported in LINQ to Entities. For more information, see Standard Query Operators in LINQ to Entities Queries. The following table lists the supported and unsupported aggregate methods.

Method Support Visual Basic function signature C# method signature
Aggregate Not supported Function Aggregate(Of TSource) ( _ source As IQueryable(Of TSource), _ func As Expression(Of Func(Of TSource, TSource, TSource)) _ ) As TSource TSource Aggregate<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, TSource, TSource>> func )
Aggregate Not supported Function Aggregate(Of TSource, TAccumulate) ( _ source As IQueryable(Of TSource), _ seed As TAccumulate, _ func As Expression(Of Func(Of TAccumulate, TSource, TAccumulate)) _ ) As TAccumulate TAccumulate Aggregate<TSource, TAccumulate>( this IQueryable<TSource> source, TAccumulate seed, Expression<Func<TAccumulate, TSource, TAccumulate>> func )
Aggregate Not supported Function Aggregate(Of TSource, TAccumulate, TResult) ( _ source As IQueryable(Of TSource), _ seed As TAccumulate, _ func As Expression(Of Func(Of TAccumulate, TSource, TAccumulate)), _ selector As Expression(Of Func(Of TAccumulate, TResult)) _ ) As TResult TResult Aggregate<TSource, TAccumulate, TResult>( this IQueryable<TSource> source, TAccumulate seed, Expression<Func<TAccumulate, TSource, TAccumulate>> func, Expression<Func<TAccumulate, TResult>> selector )
Average Supported Function Average ( _ source As IQueryable(Of Decimal) _ ) As Decimal decimal Average( this IQueryable<decimal> source )
Average Supported Function Average ( _ source As IQueryable(Of Double) _ ) As Double double Average( this IQueryable<double> source )
Average Supported Function Average ( _ source As IQueryable(Of Integer) _ ) As Double double Average( this IQueryable<int> source )
Average Supported Function Average ( _ source As IQueryable(Of Long) _ ) As Double double Average( this IQueryable<long> source )
Average Supported Function Average ( _ source As IQueryable(Of Nullable(Of Decimal)) _ ) As Nullable(Of Decimal) Nullable<decimal> Average( this IQueryable<Nullable<decimal>> source )
Average Supported Function Average ( _ source As IQueryable(Of Nullable(Of Double)) _ ) As Nullable(Of Double) Nullable<double> Average( this IQueryable<Nullable<double>> source )
Average Supported Function Average ( _ source As IQueryable(Of Nullable(Of Integer)) _ ) As Nullable(Of Double) Nullable<double> Average( this IQueryable<Nullable<int>> source )
Average Supported Function Average ( _ source As IQueryable(Of Nullable(Of Long)) _ ) As Nullable(Of Double) Nullable<double> Average( this IQueryable<Nullable<long>> source )
Average Supported Function Average ( _ source As IQueryable(Of Nullable(Of Single)) _ ) As Nullable(Of Single) Nullable<float> Average( this IQueryable<Nullable<float>> source )
Average Supported Function Average ( _ source As IQueryable(Of Single) _ ) As Single float Average( this IQueryable<float> source )
Average Not supported Function Average(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Integer)) _ ) As Double double Average<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, int>> selector )
Average Not supported Function Average(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Nullable(Of Integer))) _ ) As Nullable(Of Double) Nullable<double> Average<TSource>( this IQueryable<TSource> source, Expression<Func<TSource, Nullable<int>>> selector )
Average Not supported Function Average(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Long)) _ ) As Double double Average<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, long>> selector )
Average Not supported Function Average(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Nullable(Of Long))) _ ) As Nullable(Of Double) Nullable<double> Average<TSource>( this IQueryable<TSource> source, Expression<Func<TSource, Nullable<long>>> selector )
Average Not supported Function Average(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Single)) _ ) As Single float Average<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, float>> selector )
Average Not supported Function Average(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Nullable(Of Single))) _ ) As Nullable(Of Single) Nullable<float> Average<TSource>( this IQueryable<TSource> source, Expression<Func<TSource, Nullable<float>>> selector )
Average Not supported Function Average(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Double)) _ ) As Double double Average<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, double>> selector )
Average Not supported Function Average(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Nullable(Of Double))) _ ) As Nullable(Of Double) Nullable<double> Average<TSource>( this IQueryable<TSource> source, Expression<Func<TSource, Nullable<double>>> selector )
Average Not supported Function Average(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Decimal)) _ ) As Decimal decimal Average<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, decimal>> selector )
Average Not supported Function Average(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Nullable(Of Decimal))) _ ) As Nullable(Of Decimal) Nullable<decimal> Average<TSource>( this IQueryable<TSource> source, Expression<Func<TSource, Nullable<decimal>>> selector )
Count Supported Function Count(Of TSource) ( _ source As IQueryable(Of TSource) _ ) As Integer int Count<TSource>( this IQueryable<TSource> source )
Count Not supported Function Count(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Boolean)) _ ) As Integer int Count<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, bool>> predicate )
LongCount Supported Function LongCount(Of TSource) ( _ source As IQueryable(Of TSource) _ ) As Long long LongCount<TSource>( this IQueryable<TSource> source )
LongCount Not supported Function LongCount(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Boolean)) _ ) As Long long LongCount<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, bool>> predicate )
Max Supported Function Max(Of TSource) ( _ source As IQueryable(Of TSource) _ ) As TSource TSource Max<TSource>( this IQueryable<TSource> source )
Max Not supported Function Max(Of TSource, TResult) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, TResult)) _ ) As TResult TResult Max<TSource, TResult>( this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector )
Min Supported Function Min(Of TSource) ( _ source As IQueryable(Of TSource) _ ) As TSource TSource Min<TSource>( this IQueryable<TSource> source )
Min Not supported Function Min(Of TSource, TResult) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, TResult)) _ ) As TResult TResult Min<TSource, TResult>( this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector )
Sum Supported Function Sum ( _ source As IQueryable(Of Decimal) _ ) As Decimal decimal Sum( this IQueryable<decimal> source )
Sum Supported Function Sum ( _ source As IQueryable(Of Double) _ ) As Double double Sum( this IQueryable<double> source
Sum Supported Function Sum ( _ source As IQueryable(Of Integer) _ ) As Integer int Sum( this IQueryable<int> source )
Sum Supported Function Sum ( _ source As IQueryable(Of Long) _ ) As Long long Sum( this IQueryable<long> source )
Sum Supported Function Sum ( _ source As IQueryable(Of Nullable(Of Decimal)) _ ) As Nullable(Of Decimal) Nullable<decimal> Sum( this IQueryable<Nullable<decimal>> source )
Sum Supported Function Sum ( _ source As IQueryable(Of Nullable(Of Double)) _ ) As Nullable(Of Double) Function Sum ( _ source As IQueryable(Of Nullable(Of Double)) _ ) As Nullable(Of Double)Nullable<double> Sum( this IQueryable<Nullable<double>> source )
Sum Supported Function Sum ( _ source As IQueryable(Of Nullable(Of Integer)) _ ) As Nullable(Of Integer) Nullable<int> Sum( this IQueryable<Nullable<int>> source )
Sum Supported Function Sum ( _ source As IQueryable(Of Nullable(Of Long)) _ ) As Nullable(Of Long) Nullable<long> Sum( this IQueryable<Nullable<long>> source )
Sum Supported Function Sum ( _ source As IQueryable(Of Nullable(Of Single)) _ ) As Nullable(Of Single) Nullable<float> Sum( this IQueryable<Nullable<float>> source )
Sum Supported Function Sum ( _ source As IQueryable(Of Single) _ ) As Single float Sum( this IQueryable<float> source )
Sum Not supported Function Sum(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Integer)) _ ) As Integer int Sum<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, int>> selector )
Sum Not supported Function Sum(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Nullable(Of Integer))) _ ) As Nullable(Of Integer) Nullable<int> Sum<TSource>( this IQueryable<TSource> source, Expression<Func<TSource, Nullable<int>>> selector )
Sum Not supported Function Sum(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Long)) _ ) As Long long Sum<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, long>> selector )
Sum Not supported Function Sum(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Nullable(Of Long))) _ ) As Nullable(Of Long) Nullable<long> Sum<TSource>( this IQueryable<TSource> source, Expression<Func<TSource, Nullable<long>>> selector )
Sum Not supported Function Sum(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Nullable(Of Single))) _ ) As Nullable(Of Single) Nullable<float> Sum<TSource>( this IQueryable<TSource> source, Expression<Func<TSource, Nullable<float>>> selector )
Sum Not supported Function Sum(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Single)) _ ) As Single float Sum<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, float>> selector )
Sum Not supported Function Sum(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Double)) _ ) As Double double Sum<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, double>> selector )
Sum Not supported Function Sum(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Nullable(Of Double))) _ ) As Nullable(Of Double) Nullable<double> Sum<TSource>( this IQueryable<TSource> source, Expression<Func<TSource, Nullable<double>>> selector )
Sum Not supported Function Sum(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Decimal)) _ ) As Decimal decimal Sum<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, decimal>> selector )
Sum Not supported Function Sum(Of TSource) ( _ source As IQueryable(Of TSource), _ selector As Expression(Of Func(Of TSource, Nullable(Of Decimal))) _ ) As Nullable(Of Decimal) Nullable<decimal> Sum<TSource>( this IQueryable<TSource> source, Expression<Func<TSource, Nullable<decimal>>> selector )

Type Methods

The LINQ standard query operators that deal with CLR type conversion and testing are supported in the Entity Framework. Only CLR types that map to conceptual model types are supported in LINQ to Entities. For a list of conceptual model types, see Conceptual Model Types (CSDL). The following table lists the supported and unsupported type methods.

Method Support Visual Basic function signature C# method signature
Cast Supported for EDM primitive types Function Cast(Of TResult) ( _ source As IQueryable _ ) As IQueryable(Of TResult) IQueryable<TResult> Cast<TResult>( this IQueryable source )
OfType Supported for EntityType Function OfType(Of TResult) ( _ source As IQueryable _ ) As IQueryable(Of TResult) IQueryable<TResult> OfType<TResult>( this IQueryable source )

Paging Methods

A number of the LINQ paging methods are not supported in LINQ to Entities queries. For more information, see Standard Query Operators in LINQ to Entities Queries. The following table lists the supported and unsupported paging methods.

Method Support Visual Basic function signature C# method signature
ElementAt Not supported Function ElementAt(Of TSource) ( _ source As IQueryable(Of TSource), _ index As Integer _ ) As TSource TSource ElementAt<TSource>( this IQueryable<TSource> source, int index )
ElementAtOrDefault Not supported Function ElementAtOrDefault(Of TSource) ( _ source As IQueryable(Of TSource), _ index As Integer _ ) As TSource TSource ElementAtOrDefault<TSource>( this IQueryable<TSource> source, int index )
First Supported Function First(Of TSource) ( _ source As IQueryable(Of TSource) _ ) As TSource TSource First<TSource>( this IQueryable<TSource> source )
First Supported Function First(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Boolean)) _ ) As TSource TSource First<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, bool>> predicate )
FirstOrDefault Supported Function FirstOrDefault(Of TSource) ( _ source As IQueryable(Of TSource) _ ) As TSource TSource FirstOrDefault<TSource>( this IQueryable<TSource> source )
FirstOrDefault Supported Function FirstOrDefault(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Boolean)) _ ) As TSource TSource FirstOrDefault<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, bool>> predicate )
Last Not supported Function Last(Of TSource) ( _ source As IQueryable(Of TSource) _ ) As TSource TSource Last<TSource>( this IQueryable<TSource> source )
Last Not supported Function Last(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Boolean)) _ ) As TSource TSource Last<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, bool>> predicate )
LastOrDefault Not supported Function LastOrDefault(Of TSource) ( _ source As IQueryable(Of TSource) _ ) As TSource TSource LastOrDefault<TSource>( this IQueryable<TSource> source )
LastOrDefault Not supported Function LastOrDefault(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Boolean)) _ ) As TSource TSource LastOrDefault<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, bool>> predicate )
Single Supported Function Single(Of TSource) ( _ source As IQueryable(Of TSource) _ ) As TSource TSource Single<TSource>( this IQueryable<TSource> source )
Single Supported Function Single(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Boolean)) _ ) As TSource TSource Single<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, bool>> predicate )
SingleOrDefault Supported Function SingleOrDefault(Of TSource) ( _ source As IQueryable(Of TSource) _ ) As TSource TSource SingleOrDefault<TSource>( this IQueryable<TSource> source )
SingleOrDefault Supported Function SingleOrDefault(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Boolean)) _ ) As TSource TSource SingleOrDefault<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, bool>> predicate )
Skip Supported Function Skip(Of TSource) ( _ source As IQueryable(Of TSource), _ count As Integer _ ) As IQueryable(Of TSource) IQueryable<TSource> Skip<TSource>( this IQueryable<TSource> source, int count )
SkipWhile Not supported Function SkipWhile(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Boolean)) _ ) As IQueryable(Of TSource) IQueryable<TSource> SkipWhile<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, bool>> predicate )
SkipWhile Not supported Function SkipWhile(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Integer, Boolean)) _ ) As IQueryable(Of TSource) IQueryable<TSource> SkipWhile<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, int, bool>> predicate )
Take Supported Function Take(Of TSource) ( _ source As IQueryable(Of TSource), _ count As Integer _ ) As IQueryable(Of TSource) IQueryable<TSource> Take<TSource>( this IQueryable<TSource> source, int count )
TakeWhile Not supported Function TakeWhile(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Boolean)) _ ) As IQueryable(Of TSource) IQueryable<TSource> TakeWhile<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, bool>> predicate )
TakeWhile Not supported Function TakeWhile(Of TSource) ( _ source As IQueryable(Of TSource), _ predicate As Expression(Of Func(Of TSource, Integer, Boolean)) _ ) As IQueryable(Of TSource) IQueryable<TSource> TakeWhile<TSource>( this IQueryable<TSource> source, Expression<Func\<TSource, int, bool>> predicate )

See also

Known Issues and Considerations in LINQ to Entities

This section provides information about known issues with LINQ to Entities queries.

LINQ Queries That cannot be Cached

Starting with .NET Framework 4.5, LINQ to Entities queries are automatically cached. However, LINQ to Entities queries that apply the Enumerable.Contains operator to in-memory collections are not automatically cached. Also parameterizing in-memory collections in compiled LINQ queries is not allowed.

Ordering Information Lost

Projecting columns into an anonymous type will cause ordering information to be lost in some queries that are executed against a SQL Server 2005 database set to a compatibility level of "80". This occurs when a column name in the order-by list matches a column name in the selector, as shown in the following example:

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    // Ordering information is lost when executed against a SQL Server 2005
    // database running with a compatibility level of "80".
    var results = context.Contacts.SelectMany(c => c.SalesOrderHeaders)
        .OrderBy(c => c.SalesOrderDetails.Count)
        .Select(c => new { c.SalesOrderDetails.Count });

    foreach (var result in results)
        Console.WriteLine(result.Count);

}

Unsigned Integers Not Supported

Specifying an unsigned integer type in a LINQ to Entities query is not supported because the Entity Framework does not support unsigned integers. If you specify an unsigned integer, an ArgumentException exception will be thrown during the query expression translation, as shown in the following example. This example queries for an order with ID 48000.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    uint s = UInt32.Parse("48000");

    IQueryable<SalesOrderDetail> query = from sale in context.SalesOrderDetails
                                         where sale.SalesOrderID == s
                                         select sale;

    // NotSupportedException exception is thrown here.
    try
    {
        foreach (SalesOrderDetail order in query)
            Console.WriteLine("SalesOrderID: " + order.SalesOrderID);
    }
    catch (NotSupportedException ex)
    {
        Console.WriteLine("Exception: {0}", ex.Message);
    }
}

Type Conversion Errors

In Visual Basic, when a property is mapped to a column of SQL Server bit type with a value of 1 using the CByte function, a SqlException is thrown with an "Arithmetic overflow error" message. The following example queries the Product.MakeFlag column in the AdventureWorks sample database and an exception is thrown when the query results are iterated over.

VB
Using context As New AdventureWorksEntities()
    Dim productsList = _
        From product In context.Products _
        Select CByte(product.MakeFlag)

    ' Throws an SqlException exception with a "Arithmetic overflow error 
    ' for data type tinyint" message when a value of 1 is iterated over.
    For Each makeFlag In productsList
        Console.WriteLine(makeFlag)
    Next
End Using

Referencing Non-Scalar Variables Not Supported

Referencing a non-scalar variables, such as an entity, in a query is not supported. When such a query executes, a NotSupportedException exception is thrown with a message that states "Unable to create a constant value of type EntityType. Only primitive types ('such as Int32, String, and Guid') are supported in this context."

Note

Referencing a collection of scalar variables is supported.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    Contact contact = context.Contacts.FirstOrDefault();

    // Referencing a non-scalar closure in a query will
    // throw an exception when the query is executed.
    IQueryable<string> contacts = from c in context.Contacts
        where c == contact
        select c.LastName;

    try
    {
        foreach (string name in contacts)
        {
            Console.WriteLine("Name: ", name);
        }
    }
    catch (NotSupportedException ex)
    {
        Console.WriteLine(ex.Message);
    }
}

Nested Queries May Fail with SQL Server 2000

With SQL Server 2000, LINQ to Entities queries may fail if they produce nested Transact-SQL queries that are three or more levels deep.

Projecting to an Anonymous Type

If you define your initial query path to include related objects by using the Include method on the ObjectQuery<T> and then use LINQ to project the returned objects to an anonymous type, the objects specified in the include method are not included in the query results.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var resultWithoutRelatedObjects =
        context.Contacts.Include("SalesOrderHeaders").Select(c => new { c }).FirstOrDefault();
    if (resultWithoutRelatedObjects.c.SalesOrderHeaders.Count == 0)
    {
        Console.WriteLine("No orders are included.");
    }
}

To get related objects, do not project returned types to an anonymous type.

C#
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var resultWithRelatedObjects =
        context.Contacts.Include("SalesOrderHeaders").Select(c => c).FirstOrDefault();
    if (resultWithRelatedObjects.SalesOrderHeaders.Count != 0)
    {
        Console.WriteLine("Orders are included.");
    }
}

See also

Entity SQL Language

Entity SQL is a storage-independent query language that is similar to SQL. Entity SQL allows you to query entity data, either as objects or in a tabular form. You should consider using Entity SQL in the following cases:

  • When a query must be dynamically constructed at runtime. In this case, you should also consider using the query builder methods of ObjectQuery<T> instead of constructing an Entity SQL query string at runtime.

  • When you want to define a query as part of the model definition. Only Entity SQL is supported in a data model. For more information, see QueryView Element (MSL)

  • When using EntityClient to return read-only entity data as rowsets using a EntityDataReader. For more information, see EntityClient Provider for the Entity Framework.

  • If you are already an expert in SQL-based query languages, Entity SQL may seem the most natural to you.

Using Entity SQL with the EntityClient provider

If you want to use Entity SQL with the EntityClient provider, see the following topics for more information:

EntityClient Provider for the Entity Framework

How to: Build an EntityConnection Connection String

How to: Execute a Query that Returns PrimitiveType Results

How to: Execute a Query that Returns StructuralType Results

How to: Execute a Query that Returns RefType Results

How to: Execute a Query that Returns Complex Types

How to: Execute a Query that Returns Nested Collections

How to: Execute a Parameterized Entity SQL Query Using EntityCommand

How to: Execute a Parameterized Stored Procedure Using EntityCommand

How to: Execute a Polymorphic Query

How to: Navigate Relationships with the Navigate Operator

Using Entity SQL with object queries

If you want to use Entity SQL with object queries, see the following topics for more information:

How to: Execute a Query that Returns Entity Type Objects

How to: Execute a Parameterized Query

How to: Navigate Relationships Using Navigation Properties

How to: Call a User-Defined Function

How to: Filter Data

How to: Sort Data

How to: Group Data

How to: Aggregate Data

How to: Execute a Query that Returns Anonymous Type Objects

How to: Execute a Query that Returns a Collection of Primitive Types

How to: Query Related Objects in an EntityCollection

How to: Order the Union of Two Queries

How to: Page Through Query Results

In This Section

Entity SQL Overview

Entity SQL Reference

See also

Entity SQL Overview

Entity SQL is a SQL-like language that enables you to query conceptual models in the Entity Framework. Conceptual models represent data as entities and relationships, and Entity SQL allows you to query those entities and relationships in a format that is familiar to those who have used SQL.

The Entity Framework works with storage-specific data providers to translate generic Entity SQL into storage-specific queries. The EntityClient provider supplies a way to execute an Entity SQL command against an entity model and return rich types of data including scalar results, result sets, and object graphs. When you construct EntityCommand objects, you can specify a stored procedure name or the text of a query by assigning an Entity SQL query string to its EntityCommand.CommandText property. The EntityDataReader exposes the results of executing a EntityCommand against an EDM. To execute the command that returns the EntityDataReader, call ExecuteReader.

In addition to the EntityClient provider, the Entity Framework enables you to use Entity SQL to execute queries against a conceptual model and return data as strongly-typed CLR objects that are instances of entity types. For more information, see Working with Objects.

This section provides conceptual information about Entity SQL.

In This Section

How Entity SQL Differs from Transact-SQL

Entity SQL Quick Reference

Type System

Type Definitions

Constructing Types

Query Plan Caching

Namespaces

Identifiers

Parameters

Variables

Unsupported Expressions

Literals

Null Literals and Type Inference

Input Character Set

Query Expressions

Functions

Operator Precedence

Paging

Comparison Semantics

Composing Nested Entity SQL Queries

Nullable Structured Types

See also

How Entity SQL Differs from Transact-SQL

This topic describes the differences between Entity SQL and Transact-SQL.

Inheritance and Relationships Support

Entity SQL works directly with conceptual entity schemas and supports conceptual model features such as inheritance and relationships.

When working with inheritance, it is often useful to select instances of a subtype from a collection of supertype instances. The oftype operator in Entity SQL (similar to oftype in C# Sequences) provides this capability.

Support for Collections

Entity SQL treats collections as first-class entities. For example:

  • Collection expressions are valid in a from clause.

  • in and exists subqueries have been generalized to allow any collections.

    A subquery is one kind of collection. e1 in e2 and exists(e) are the Entity SQL constructs to perform these operations.

  • Set operations, such as union, intersect, and except, now operate on collections.

  • Joins operate on collections.

Support for Expressions

Transact-SQL has subqueries (tables) and expressions (rows and columns).

To support collections and nested collections, Entity SQL makes everything an expression. Entity SQL is more composable than Transact-SQL—every expression can be used anywhere. Query expressions always result in collections of the projected types and can be used anywhere a collection expression is allowed. For information about Transact-SQL expressions that are not supported in Entity SQL, see Unsupported Expressions.

The following are all valid Entity SQL queries:

1+2 *3  
"abc"  
row(1 as a, 2 as b)  
{ 1, 3, 5}   
e1 union all e2  
set(e1)  

Uniform Treatment of Subqueries

Given its emphasis on tables, Transact-SQL performs contextual interpretation of subqueries. For example, a subquery in the from clause is considered to be a multiset (table). But the same subquery used in the select clause is considered to be a scalar subquery. Similarly, a subquery used on the left side of an in operator is considered to be a scalar subquery, while the right side is expected to be a multiset subquery.

Entity SQL eliminates these differences. An expression has a uniform interpretation that does not depend on the context in which it is used. Entity SQL considers all subqueries to be multiset subqueries. If a scalar value is desired from the subquery, Entity SQL provides the anyelement operator that operates on a collection (in this case, the subquery), and extracts a singleton value from the collection.

Avoiding Implicit Coercions for Subqueries

A related side effect of uniform treatment of subqueries is implicit conversion of subqueries to scalar values. Specifically, in Transact-SQL, a multiset of rows (with a single field) is implicitly converted into a scalar value whose data type is that of the field.

Entity SQL does not support this implicit coercion. Entity SQL provides the ANYELEMENT operator to extract a singleton value from a collection, and a select value clause to avoid creating a row-wrapper during a query expression.

Select Value: Avoiding the Implicit Row Wrapper

The select clause in a Transact-SQL subquery implicitly creates a row wrapper around the items in the clause. This implies that we cannot create collections of scalars or objects. Transact-SQL allows an implicit coercion between a rowtype with one field, and a singleton value of the same data type.

Entity SQL provides the select value clause to skip the implicit row construction. Only one item may be specified in a select value clause. When such a clause is used, no row wrapper is constructed around the items in the select clause, and a collection of the desired shape may be produced, for example: select value a.

Entity SQL also provides the row constructor to construct arbitrary rows. select takes one or more elements in the projection and results in a data record with fields, as follows:

select a, b, c

Left Correlation and Aliasing

In Transact-SQL, expressions in a given scope (a single clause like select or from) cannot reference expressions defined earlier in the same scope. Some dialects of SQL (including Transact-SQL) do support limited forms of these in the from clause.

Entity SQL generalizes left correlations in the from clause, and treats them uniformly. Expressions in the from clause can reference earlier definitions (definitions to the left) in the same clause without the need for additional syntax.

Entity SQL also imposes additional restrictions on queries involving group by clauses. Expressions in the select clause and having clause of such queries may only refer to the group by keys via their aliases. The following construct is valid in Transact-SQL but are not in Entity SQL:

select t.x + t.y from T as t group by t.x + t.y  

To do this in Entity SQL:

select k from T as t group by (t.x + t.y) as k  

Referencing Columns (Properties) of Tables (Collections)

All column references in Entity SQL must be qualified with the table alias. The following construct (assuming that a is a valid column of table T) is valid in Transact-SQL but not in Entity SQL.

select a from T  

The Entity SQL form is

select t.a as A from T as t  

The table aliases are optional in the from clause. The name of the table is used as the implicit alias. Entity SQL allows the following form as well:

select Tab.a from Tab  

Navigation Through Objects

Transact-SQL uses the "." notation for referencing columns of (a row of) a table. Entity SQL extends this notation (borrowed from programming languages) to support navigation through properties of an object.

For example, if p is an expression of type Person, the following is the Entity SQL syntax for referencing the city of the address of this person.

p.Address.City   

No Support for *

Transact-SQL supports the unqualified * syntax as an alias for the entire row, and the qualified * syntax (t.*) as a shortcut for the fields of that table. In addition, Transact-SQL allows for a special count(*) aggregate, which includes nulls.

Entity SQL does not support the * construct. Transact-SQL queries of the form select * from T and select T1.* from T1, T2... can be expressed in Entity SQL as select value t from T as t and select value t1 from T1 as t1, T2 as t2..., respectively. Additionally, these constructs handle inheritance (value substitutability), while the select * variants are restricted to top-level properties of the declared type.

Entity SQL does not support the count(*) aggregate. Use count(0) instead.

Changes to Group By

Entity SQL supports aliasing of group by keys. Expressions in the select clause and having clause must refer to the group by keys via these aliases. For example, this Entity SQL syntax:

select k1, count(t.a), sum(t.a)  
from T as t  
group by t.b + t.c as k1  

...is equivalent to the following Transact-SQL:

select b + c, count(*), sum(a)   
from T  
group by b + c  

Collection-Based Aggregates

Entity SQL supports two kinds of aggregates.

Collection-based aggregates operate on collections and produce the aggregated result. These can appear anywhere in the query, and do not require a group by clause. For example:

select t.a as a, count({1,2,3}) as b from T as t     

Entity SQL also supports SQL-style aggregates. For example:

select a, sum(t.b) from T as t group by t.a as a  

ORDER BY Clause Usage

Transact-SQL allows ORDER BY clauses to be specified only in the topmost SELECT .. FROM .. WHERE block. In Entity SQL you can use a nested ORDER BY expression and it can be placed anywhere in the query, but ordering in a nested query is not preserved.

-- The following query will order the results by the last name  
SELECT C1.FirstName, C1.LastName  
        FROM AdventureWorks.Contact as C1  
        ORDER BY C1.LastName  
-- In the following query ordering of the nested query is ignored.  
SELECT C2.FirstName, C2.LastName  
    FROM (SELECT C1.FirstName, C1.LastName  
        FROM AdventureWorks.Contact as C1  
        ORDER BY C1.LastName) as C2  

Identifiers

In Transact-SQL, identifier comparison is based on the collation of the current database. In Entity SQL, identifiers are always case insensitive and accent sensitive (that is, Entity SQL distinguishes between accented and unaccented characters; for example, 'a' is not equal to 'ấ'). Entity SQL treats versions of letters that appear the same but are from different code pages as different characters. For more information, see Input Character Set.

Transact-SQL Functionality Not Available in Entity SQL

The following Transact-SQL functionality is not available in Entity SQL.

DML
Entity SQL currently provides no support for DML statements (insert, update, delete).

DDL
Entity SQL provides no support for DDL in the current version.

Imperative Programming
Entity SQL provides no support for imperative programming, unlike Transact-SQL. Use a programming language instead.

Grouping Functions
Entity SQL does not yet provide support for grouping functions (for example, CUBE, ROLLUP, and GROUPING_SET).

Analytic Functions
Entity SQL does not (yet) provide support for analytic functions.

Built-in Functions, Operators
Entity SQL supports a subset of Transact-SQL's built in functions and operators. These operators and functions are likely to be supported by the major store providers. Entity SQL uses the store-specific functions declared in a provider manifest. Additionally, the Entity Framework allows you to declare built-in and user-defined existing store functions, for Entity SQL to use.

Hints
Entity SQL does not provide mechanisms for query hints.

Batching Query Results
Entity SQL does not support batching query results. For example, the following is valid Transact-SQL (sending as a batch):

select * from products;  
select * from catagories;  

However, the equivalent Entity SQL is not supported:

Select value p from Products as p;  
Select value c from Categories as c;  

Entity SQL only supports one result-producing query statement per command.

See also

Entity SQL Quick Reference

This topic provides a quick reference to Entity SQL queries. The queries in this topic are based on the AdventureWorks Sales model.

Literals

String

There are Unicode and non-Unicode character string literals. Unicode strings are prepended with N. For example, N'hello'.

The following is an example of a Non-Unicode string literal:

'hello'  
--same as  
"hello"  

Output:

Value
hello

DateTime

In DateTime literals, both date and time parts are mandatory. There are no default values.

Example:

DATETIME '2006-12-25 01:01:00.000'   
--same as  
DATETIME '2006-12-25 01:01'  

Output:

Value
12/25/2006 1:01:00 AM

Integer

Integer literals can be of type Int32 (123), UInt32 (123U), Int64 (123L), and UInt64 (123UL).

Example:

--a collection of integers  
{1, 2, 3}  

Output:

Value
1
2
3

Other

Other literals supported by Entity SQL are Guid, Binary, Float/Double, Decimal, and null. Null literals in Entity SQL are considered to be compatible with every other type in the conceptual model.

Type Constructors

ROW

ROW constructs an anonymous, structurally-typed (record) value as in: ROW(1 AS myNumber, ‘Name’ AS myName).

Example:

SELECT VALUE row (product.ProductID as ProductID, product.Name   
    as ProductName) FROM AdventureWorksEntities.Product AS product  

Output:

ProductID Name
1 Adjustable Race
879 All-Purpose Bike Stand
712 AWC Logo Cap
... ...

MULTISET

MULTISET constructs collections, such as:

MULTISET(1,2,2,3) --same as-{1,2,2,3}.

Example:

SELECT VALUE product FROM AdventureWorksEntities.Product AS product WHERE product.ListPrice IN MultiSet (125, 300)  

Output:

ProductID Name ProductNumber
842 Touring-Panniers, Large PA-T100

Object

Named Type Constructor constructs (named) user-defined objects, such as person("abc", 12).

Example:

SELECT VALUE AdventureWorksModel.SalesOrderDetail (o.SalesOrderDetailID, o.CarrierTrackingNumber, o.OrderQty,   
o.ProductID, o.SpecialOfferID, o.UnitPrice, o.UnitPriceDiscount,   
o.rowguid, o.ModifiedDate) FROM AdventureWorksEntities.SalesOrderDetail   
AS o  

Output:

SalesOrderDetailID CarrierTrackingNumber OrderQty ProductID ...
1 4911-403C-98 1 776 ...
2 4911-403C-98 3 777 ...
... ... ... ... ...

References

REF

REF creates a reference to an entity type instance. For example, the following query returns references to each Order entity in the Orders entity set:

SELECT REF(o) AS OrderID FROM Orders AS o  

Output:

Value
1
2
3
...

The following example uses the property extraction operator (.) to access a property of an entity. When the property extraction operator is used, the reference is automatically dereferenced.

Example:

SELECT VALUE REF(p).Name FROM   
    AdventureWorksEntities.Product as p  

Output:

Value
Adjustable Race
All-Purpose Bike Stand
AWC Logo Cap
...

DEREF

DEREF dereferences a reference value and produces the result of that dereference. For example, the following query produces the Order entities for each Order in the Orders entity set: SELECT DEREF(o2.r) FROM (SELECT REF(o) AS r FROM LOB.Orders AS o) AS o2..

Example:

SELECT VALUE DEREF(REF(p)).Name FROM   
    AdventureWorksEntities.Product as p  

Output:

Value
Adjustable Race
All-Purpose Bike Stand
AWC Logo Cap
...

CREATEREF AND KEY

CREATEREF creates a reference passing a key. KEY extracts the key portion of an expression with type reference.

Example:

SELECT VALUE Key(CreateRef(AdventureWorksEntities.Product, row(p.ProductID)))   
    FROM AdventureWorksEntities.Product as p  

Output:

ProductID
980
365
771
...

Functions

Canonical

The namespace for canonical functions is Edm, as in Edm.Length("string"). You do not have to specify the namespace unless another namespace is imported that contains a function with the same name as a canonical function. If two namespaces have the same function, the user should specific the full name.

Example:

SELECT Length(c. FirstName) As NameLen FROM   
    AdventureWorksEntities.Contact AS c   
    WHERE c.ContactID BETWEEN 10 AND 12  

Output:

NameLen
6
6
5

Microsoft Provider-Specific

Microsoft provider-specific functions are in the SqlServer namespace.

Example:

SELECT SqlServer.LEN(c.EmailAddress) As EmailLen FROM   
    AdventureWorksEntities.Contact AS c WHERE   
    c.ContactID BETWEEN 10 AND 12  

Output:

EmailLen
27
27
26

Namespaces

USING specifies namespaces used in a query expression.

Example:

using SqlServer; LOWER('AA');  

Output:

Value
aa

Paging

Paging can be expressed by declaring a SKIP and LIMIT sub-clauses to the ORDER BY clause.

Example:

SELECT c.ContactID as ID, c.LastName as Name FROM   
    AdventureWorks.Contact AS c ORDER BY c.ContactID SKIP 9 LIMIT 3;  

Output:

ID Name
10 Adina
11 Agcaoili
12 Aguilar

Grouping

GROUPING BY specifies groups into which objects returned by a query (SELECT) expression are to be placed.

Example:

SELECT VALUE name FROM AdventureWorksEntities.Product as P   
    GROUP BY P.Name HAVING MAX(P.ListPrice) > 5  

Output:

name
LL Mountain Seat Assembly
ML Mountain Seat Assembly
HL Mountain Seat Assembly
...

Navigation

The relationship navigation operator allows you to navigate over the relationship from one entity (from end) to another (to end). NAVIGATE takes the relationship type qualified as <namespace>.<relationship type name>. Navigate returns Ref<T> if the cardinality of the to end is 1. If the cardinality of the to end is n, the Collection<Ref<T>> will be returned.

Example:

SELECT a.AddressID, (SELECT VALUE DEREF(v) FROM   
    NAVIGATE(a, AdventureWorksModel.FK_SalesOrderHeader_Address_BillToAddressID) AS v)   
    FROM AdventureWorksEntities.Address AS a  

Output:

AddressID
1
2
3
...

SELECT VALUE AND SELECT

SELECT VALUE

Entity SQL provides the SELECT VALUE clause to skip the implicit row construction. Only one item can be specified in a SELECT VALUE clause. When such a clause is used, no row wrapper is constructed around the items in the SELECT clause, and a collection of the desired shape can be produced, for example: SELECT VALUE a.

Example:

SELECT VALUE p.Name FROM AdventureWorksEntities.Product as p  

Output:

Name
Adjustable Race
All-Purpose Bike Stand
AWC Logo Cap
...

SELECT

Entity SQL also provides the row constructor to construct arbitrary rows. SELECT takes one or more elements in the projection and results in a data record with fields, for example: SELECT a, b, c.

Example:

SELECT p.Name, p.ProductID FROM AdventureWorksEntities.Product as p Output:

Name ProductID
Adjustable Race 1
All-Purpose Bike Stand 879
AWC Logo Cap 712
... ...

CASE EXPRESSION

The case expression evaluates a set of Boolean expressions to determine the result.

Example:

CASE WHEN AVG({25,12,11}) < 100 THEN TRUE ELSE FALSE END  

Output:

Value
TRUE

See also

Type System (Entity SQL)

Entity SQL supports a number of types:

This section discusses the anonymous types that are not defined in the schema explicitly but are supported by Entity SQL. For information on primitive and nominal types, see Conceptual Model Types (CSDL).

Rows

The structure of a row depends on the sequence of typed and named members that the row consists of. A row type has no identity and cannot be inherited from. Instances of the same row type are equivalent if the members are respectively equivalent. Rows have no behavior beyond their structural equivalence and have no equivalent in the common language runtime. Queries can result in structures that contain rows or collections of rows. The API binding between the Entity SQL queries and the host language defines how rows are realized in the query that produced the result. For information on how to construct a row instance, see Constructing Types.

Collections

Collection types represent zero or more instances of other objects. For information on how to construct collection, see Constructing Types.

References

A reference is a logical pointer to a specific entity in a specific entity set.

Entity SQL supports the following operators to construct, deconstruct, and navigate through references:

You can navigate through a reference by using the member access (dot) operator(.). The following snippet extracts the Id property (of Order) by navigating through the r (reference) property.

select o2.r.Id   
from (select ref(o) as r from LOB.Orders as o) as o2   

If the reference value is null, or if the target of the reference does not exist, the result is null.

See also

Type Definitions (Entity SQL)

A type definition is used in the declaration statement of an Entity SQL Inline function.

Remarks

The declaration statement for an inline function consists of the FUNCTION keyword followed by the identifier representing the function name (for example, "MyAvg") followed by a parameter definition list in parenthesis (for example, "dues Collection(Decimal)").

The parameter definition list consists of zero or more parameter definitions. Each parameter definition consists of an identifier (the name of the parameter to the function, for example, "dues") followed by a type definition (for example, "Collection(Decimal)").

The type definitions can be either:

  • The type of the identifier (for example, "Int32" or "AdventureWorks.Order").

  • The keyword COLLECTION followed by another type definition in parenthesis (for example, "Collection(AdventureWorks.Order)").

  • The keyword ROW followed by a list of property definitions in parenthesis (for example, "Row(x AdventureWorks.Order)"). Property definitions have a format such as "identifier type_definition, identifier type_definition, ...".

  • The keyword REF followed by the type of the identifier in parenthesis (for example, "Ref(AdventureWorks.Order)"). The REF type definition operator requires an entity type as the argument. You cannot specify a primitive type as the argument.

You can also nest type definitions (for example, "Collection(Row(x Ref(AdventureWorks.Order)))").

The type definition options are:

  • IdentifierName supported_type, or

  • IdentifierName COLLECTION(type_definition), or

  • IdentifierName ROW(property_definition), or

  • IdentifierName REF(supported_entity_type)

The property definition option is IdentifierName type_definition.

Supported types are any types in the current namespace. These include both primitive and entity types.

Supported entity types refer to only entity types in the current namespace. They do not include primitive types.

Examples

The following is an example of a simple type definition.

USING Microsoft.Samples.Entity  
Function MyRound(p1 EDM.Decimal) AS (  
   Round(p1)  
)  
MyRound(CAST(1.7 as EDM.Decimal))  

The following is an example of a COLLECTION type definition.

USING Microsoft.Samples.Entity  
Function MyRound(p1 Collection(EDM.Decimal)) AS (  
   Select Round(p1) from p1  
)  
MyRound({CAST(1.7 as EDM.Decimal), CAST(2.7 as EDM.Decimal)})  

The following is an example of a ROW type definition.

USING Microsoft.Samples.Entity  
Function MyRound(p1 Row(x EDM.Decimal)) AS (  
   Round(p1.x)  
)  
select MyRound(row(a as x)) from {CAST(1.7 as EDM.Decimal), CAST(2.7 as EDM.Decimal)} as a  

The following is an example of a REF type definition.

USING Microsoft.Samples.Entity  
Function UnReference(p1 Ref(AdventureWorks.Order)) AS (  
   Deref(p1)  
)  
select Ref(x) from AdventureWorksEntities.SalesOrderHeaders as x  

See also

Constructing Types (Entity SQL)

Entity SQL provides three kinds of constructors: row constructors, named type constructors, and collection constructors.

Row Constructors

You use row constructors in Entity SQL to construct anonymous, structurally typed records from one or more values. The result type of a row constructor is a row type whose field types correspond to the types of the values used to construct the row. For example, the following expression constructs a value of type Record(a int, b string, c int):

ROW(1 AS a, "abc" AS b, a + 34 AS c)

If you do not provide an alias for an expression in a row constructor, the Entity Framework will try to generate one. For more information, see the "Aliasing Rules" section in Identifiers.

The following rules apply to expression aliasing in a row constructor:

  • Expressions in a row constructor cannot refer to other aliases in the same constructor.

  • Two expressions in the same row constructor cannot have the same alias.

For more information about row constructors, see ROW.

Collection Constructors

You use collection constructors in Entity SQL to create an instance of a multiset from a list of values. All the values in the constructor must be of mutually compatible type T, and the constructor produces a collection of type Multiset<T>. For example, the following expression creates a collection of integers:

Multiset(1, 2, 3)

{1, 2, 3}

Empty multiset constructors are not allowed because the type of the elements cannot be determined. The following is not valid:

multiset() {}

For more information, see MULTISET.

Named Type Constructors (NamedType Initializers)

Entity SQL allows type constructors (initializers) to create instances of named complex types and entity types. For example, the following expression creates an instance of a Person type.

Person("abc", 12)

The following expression creates an instance of a complex type.

MyModel.ZipCode(‘98118’, ‘4567’)

The following expression creates an instance of a nested complex type.

MyModel.AddressInfo('My street address', 'Seattle', 'WA', MyModel.ZipCode('98118', '4567'))

The following expression creates an instance of an entity with a nested complex type.

MyModel.Person("Bill", MyModel.AddressInfo('My street address', 'Seattle', 'WA', MyModel.ZipCode('98118', '4567')))

The following example shows how to initialize a property of a complex type to null. MyModel.ZipCode(‘98118’, null)

The arguments to the constructor are assumed to be in the same order as the declaration of the attributes of the type.

For more information, see Named Type Constructor.

See also

Query Plan Caching (Entity SQL)

Whenever an attempt to execute a query is made, the query pipeline looks up its query plan cache to see whether the exact query is already compiled and available. If so, it reuses the cached plan rather than building a new one. If a match is not found in the query plan cache, the query is compiled and cached. A query is identified by its Entity SQL text and parameter collection (names and types). All text comparisons are case-sensitive.

Configuration

Query plan caching is configurable through the EntityCommand.

To enable or disable query plan caching through EntityCommand.EnablePlanCaching, set this property to true or false. Disabling plan caching for individual dynamic queries that are unlikely to be used more then once improves performance.

You can enable query plan caching through EnablePlanCaching.

Recommended Practice

Dynamic queries should be avoided, in general. The following dynamic query example is vulnerable to SQL injection attacks, because it takes user input directly without any validation.

"SELECT sp.SalesYTD FROM AdventureWorksEntities.SalesPerson as sp WHERE sp.EmployeeID = " + employeeTextBox.Text;

If you do use dynamically generated queries, consider disabling query plan caching to avoid unnecessary memory consumption for cache entries that are unlikely to be reused.

Query plan caching on static queries and parameterized queries can provide performance benefits. The following is an example of a static query:

"SELECT sp.SalesYTD FROM AdventureWorksEntities.SalesPerson as sp";  

For queries to be matched properly by the query plan cache, they should comply with the following requirements:

  • Query text should be a constant pattern, preferably a constant string or a resource.

  • EntityParameter or ObjectParameter should be used wherever a user-supplied value must be passed.

You should avoid the following query patterns, which unnecessarily consume slots in the query plan cache:

  • Changes to letter case in the text.

  • Changes to white space.

  • Changes to literal values.

  • Changes to text inside comments.

See also

Namespaces (Entity SQL)

Entity SQL introduces namespaces to avoid name conflicts for global identifiers such as type names, entity sets, functions, and so on. The namespace support in Entity SQL is similar to the namespace support in the .NET Framework.

Entity SQL provides two forms of the USING clause: qualified namespaces (where a shorter alias is provided for the namespace), and unqualified namespaces, as illustrated in the following example:

USING System.Data;

USING tsql = System.Data;

Name Resolution Rules

If an identifier cannot be resolved in the local scopes, Entity SQL tries to locate the name in the global scopes (the namespaces). Entity SQL first tries to match the identifier (prefix) with one of the qualified namespaces. If there is a match, Entity SQL tries to resolve the rest of the identifier in the specified namespace. If no match is found, an exception is thrown.

Next, Entity SQL tries to search all unqualified namespaces (specified in the prolog) for the identifier. If the identifier can be located in exactly one namespace, that location is returned. If more than one namespace has a match for that identifier, an exception is thrown. If no namespace can be identified for the identifier, Entity SQL passes the name onto the next outward scope (the DbCommand or DbConnection object), as illustrated in the following example:

SELECT TREAT(p AS NamespaceName.Employee)  
FROM ContainerName.Person AS p  
WHERE p IS OF (NamespaceName.Employee)  

Differences from the .NET Framework

In the .NET Framework, you can use partially qualified namespaces. Entity SQL does not allow this.

ADO.NET Usage

Queries are expressed through ADO.NET DbCommand objects. DbCommand objects can be built over DbConnection objects. Namespaces can also be specified as part of the DbCommand and DbConnection objects. If Entity SQL cannot resolve an identifier within the query itself, the external namespaces are probed (based on similar rules).

See also

Identifiers (Entity SQL)

Identifiers are used in Entity SQL to represent query expression aliases, variable references, properties of objects, functions, and so on. Entity SQL provides two kinds of identifiers: simple identifiers and quoted identifiers.

Simple Identifiers

A simple identifier in Entity SQL is a sequence of alphanumeric and underscore characters. The first character of the identifier must be an alphabetical character (a-z or A-Z).

Quoted Identifiers

A quoted identifier is any sequence of characters enclosed in square brackets ([]). Quoted identifiers let you specify identifiers with characters that are not valid in identifiers. All characters between the square brackets become part of the identifier, including all white space.

A quoted identifier cannot include the following characters:

  • Newline.

  • Carriage returns.

  • Tabs.

  • Backspace.

  • Additional square brackets (that is, square brackets within the square brackets that delineate the identifier).

A quoted-identifier can include Unicode characters.

Quoted identifiers enable you to create property name characters that are not valid in identifiers, as illustrated in the following example:

SELECT c.ContactName AS [Contact Name] FROM customers AS c

You can also use quoted identifiers to specify an identifier that is a reserved keyword of Entity SQL. For example, if the type Email has a property named "From", you can disambiguate it from the reserved keyword FROM by using square brackets, as follows:

SELECT e.[From] FROM emails AS e

You can use a quoted identifier on the right side of a dot (.) operator.

SELECT t FROM ts as t WHERE t.[property] == 2

To use the square bracket in an identifier, add an extra square bracket. In the following example "abc]" is the identifier:

SELECT t from ts as t WHERE t.[abc]]] == 2

For quoted identifier comparison semantics, see Input Character Set.

Aliasing Rules

We recommend specifying aliases in Entity SQL queries whenever needed, including the following Entity SQL constructs:

  • Fields of a row constructor.

  • Items in the FROM clause of a query expression.

  • Items in the SELECT clause of a query expression.

  • Items in the GROUP BY clause of a query expression.

Valid Aliases

Valid aliases in Entity SQL are any simple identifier or quoted identifier.

Alias Generation

If no alias is specified in an Entity SQL query expression, Entity SQL tries to generate an alias based on the following simple rules:

  • If the query expression (for which the alias is unspecified) is a simple or quoted identifier, that identifier is used as the alias. For example, ROW(a, [b]) becomes ROW(a AS a, [b] AS [b]).

  • If the query expression is a more complex expression, but the last component of that query expression is a simple identifier, then that identifier is used as the alias. For example, ROW(a.a1, b.[b1]) becomes ROW(a.a1 AS a1, b.[b1] AS [b1]).

We recommend that you do not use implicit aliasing if you want to use the alias name later. Anytime aliases (implicit or explicit) conflict or are repeated in the same scope, there will be a compile error. An implicit alias will pass compilation even if there is an explicit or implicit alias of the same name.

Implicit aliases are autogenerated based on user input. For example, the following line of code will generate NAME as an alias for both columns and therefore will conflict.

SELECT product.NAME, person.NAME  

The following line of code, which uses explicit aliases, will also fail. However, the failure will be more apparent by reading the code.

SELECT 1 AS X, 2 AS X …  

Scoping Rules

Entity SQL defines scoping rules that determine when particular variables are visible in the query language. Some expressions or statements introduce new names. The scoping rules determine where those names can be used, and when or where a new declaration with the same name as another can hide its predecessor.

When names are defined in an Entity SQL query, they are said to be defined within a scope. A scope covers an entire region of the query. All expressions or name references within a certain scope can see names that are defined within that scope. Before a scope begins and after it ends, names that are defined within the scope cannot be referenced.

Scopes can be nested. Parts of Entity SQL introduce new scopes that cover entire regions, and these regions can contain other Entity SQL expressions that also introduce scopes. When scopes are nested, references can be made to names that are defined in the innermost scope, which contains the reference. References can also be made to any names that are defined in any outer scopes. Any two scopes defined within the same scope are considered sibling scopes. References cannot be made to names that are defined within sibling scopes.

If a name declared in an inner scope matches a name declared in an outer scope, references within the inner scope or within scopes declared within that scope refer only to the newly declared name. The name in the outer scope is hidden.

Even within the same scope, names cannot be referenced before they are defined.

Global names can exist as part of the execution environment. This can include names of persistent collections or environment variables. For a name to be global, it must be declared in the outermost scope.

Parameters are not in a scope. Because references to parameters include special syntax, names of parameters will never collide with other names in the query.

Query Expressions

An Entity SQL query expression introduces a new scope. Names that are defined in the FROM clause are introduced into the from scope in order of appearance, left to right. In the join list, expressions can refer to names that were defined earlier in the list. Public properties (fields and so on) of elements identified in the FROM clause are not added to the from-scope. They must be always referenced by the alias-qualified name. Typically, all parts of the SELECT expression are considered within the from-scope.

The GROUP BY clause also introduces a new sibling scope. Each group can have a group name that refers to the collection of elements in the group. Each grouping expression will also introduce a new name into the group-scope. Additionally, the nest aggregate (or the named group) is also added to the scope. The grouping expressions themselves are within the from-scope. However, when a GROUP BY clause is used, the select-list (projection), HAVING clause, and ORDER BY clause are considered to be within the group-scope, and not the from-scope. Aggregates receive special treatment, as described in the following bulleted list.

The following are additional notes about scopes:

  • The select-list can introduce new names into the scope, in order. Projection expressions to the right might refer to names projected on the left.

  • The ORDER BY clause can refer to names (aliases) specified in the select list.

  • The order of evaluation of clauses within the SELECT expression determines the order that names are introduced into the scope. The FROM clause is evaluated first, followed by the WHERE clause, GROUP BY clause, HAVING clause, SELECT clause, and finally the ORDER BY clause.

Aggregate Handling

Entity SQL supports two forms of aggregates: collection-based aggregates and group-based aggregates. Collection-based aggregates are the preferred construct in Entity SQL, and group-based aggregates are supported for SQL compatibility.

When resolving an aggregate, Entity SQL first tries to treat it as a collection-based aggregate. If that fails, Entity SQL transforms the aggregate input into a reference to the nest aggregate and tries to resolve this new expression, as illustrated in the following example.

AVG(t.c) becomes AVG(group..(t.c))

See also

Parameters (Entity SQL)

Parameters are variables that are defined outside Entity SQL, usually through a binding API that is used by a host language. Each parameter has a name and a type. Parameter names are defined in query expressions with the at (@) symbol as a prefix. This disambiguates them from the names of properties or other names that are defined in the query.

The host-language binding API provides APIs for binding parameters.

Example

select c   
      from LOB.Customers as c   
      where c.Name = @name  

See also

Variables (Entity SQL)

Variable

A variable expression is a reference to a named expression defined in the current scope. A variable reference must be a valid Entity SQL identifier, as defined in Identifiers.

The following example shows the use of a variable in the expression. The c in the FROM clause is the definition of the variable. The use of c in the SELECT clause represents the variable reference.

select c   
from LOB.customers as c  

See also

Unsupported expressions

This topic describes Transact-SQL expressions that are not supported in Entity SQL. For more information, see How Entity SQL Differs from Transact-SQL.

Quantified predicates

Transact-SQL allows constructs of the following form:

SQL
sal > all (select salary from employees)
sal > any (select salary from employees)

Entity SQL, however, does not support such constructs. Equivalent expressions can be written in Entity SQL as follows:

SQL
not exists(select 0 from employees as e where sal <= e.salary)
exists(select 0 from employees as e where sal > e.salary)

* operator

Transact-SQL supports the use of the * operator in the SELECT clause to indicate that all columns should be projected out. This is not supported in Entity SQL.

See also

Literals (Entity SQL)

This topic describes Entity SQL support for literals.

Null

The null literal is used to represent the value null for any type. A null literal is compatible with any type.

Typed nulls can be created by a cast over a null literal. For more information, see CAST.

For rules about where free floating null literals can be used, see Null Literals and Type Inference.

Boolean

Boolean literals are represented by the keywords true and false.

Integer

Integer literals can be of type Int32 or Int64. An Int32 literal is a series of numeric characters. An Int64 literal is series of numeric characters followed by an uppercase L.

Decimal

A fixed-point number (decimal) is a series of numeric characters, a dot (.) and another series of numeric characters followed by an uppercase "M".

Float, Double

A double-precision floating point number is a series of numeric characters, a dot (.) and another series of numeric characters possibly followed by an exponent. A single-precisions floating point number (or float) is a double-precision floating point number syntax followed by the lowercase f.

String

A string is a series of characters enclosed in quote marks. Quotes can be either both single-quotes (') or both double-quotes ("). Character string literals can be either Unicode or non-Unicode. To declare a character string literal as Unicode, prefix the literal with an uppercase "N". The default is non-Unicode character string literals. There can be no spaces between the N and the string literal payload, and the N must be uppercase.

'hello' -- non-Unicode character string literal  
N'hello' -- Unicode character string literal  
"x"  
N"This is a string!"  
'so is THIS'  

DateTime

A datetime literal is independent of locale and is composed of a date part and a time part. Both date and time parts are mandatory and there are no default values.

The date part must have the format: YYYY-MM-DD, where YYYY is a four digit year value between 0001 and 9999, MM is the month between 1 and 12 and DD is the day value that is valid for the given month MM.

The time part must have the format: HH:MM[:SS[.fffffff]], where HH is the hour value between 0 and 23, MM is the minute value between 0 and 59, SS is the second value between 0 and 59 and fffffff is the fractional second value between 0 and 9999999. All value ranges are inclusive. Fractional seconds are optional. Seconds are optional unless fractional seconds are specified; in this case, seconds are required. When seconds or fractional seconds are not specified, the default value of zero will be used instead.

There can be any number of spaces between the DATETIME symbol and the literal payload, but no new lines.

DATETIME'2006-10-1 23:11'  
DATETIME'2006-12-25 01:01:00.0000000' -- same as DATETIME'2006-12-25 01:01'  

Time

A time literal is independent of locale and composed of a time part only. The time part is mandatory and there is no default value. It must have the format HH:MM[:SS[.fffffff]], where HH is the hour value between 0 and 23, MM is the minute value between 0 and 59, SS is the second value between 0 and 59, and fffffff is the second fraction value between 0 and 9999999. All value ranges are inclusive. Fractional seconds are optional. Seconds are optional unless fractional seconds are specified; in this case, seconds are required. When seconds or fractions are not specified, the default value of zero will be used instead.

There can be any number of spaces between the TIME symbol and the literal payload, but no new lines.

TIME‘23:11’  
TIME‘01:01:00.1234567’  

DateTimeOffset

A datetimeoffset literal is independent of locale and composed of a date part, a time part, and an offset part. All date, time, and offset parts are mandatory and there are no default values. The date part must have the format YYYY-MM-DD, where YYYY is a four digit year value between 0001 and 9999, MM is the month between 1 and 12, and DD is the day value that is valid for the given month. The time part must have the format HH:MM[:SS[.fffffff]], where HH is the hour value between 0 and 23, MM is the minute value between 0 and 59, SS is the second value between 0 and 59, and fffffff is the fractional second value between 0 and 9999999. All value ranges are inclusive. Fractional seconds are optional. Seconds are optional unless fractional seconds are specified; in this case, seconds are required. When seconds or fractions are not specified, the default value of zero will be used instead. The offset part must have the format {+|-}HH:MM, where HH and MM have the same meaning as in the time part. The range of the offset, however, must be between -14:00 and + 14:00

There can be any number of spaces between the DATETIMEOFFSET symbol and the literal payload, but no new lines.

DATETIMEOFFSET‘2006-10-1 23:11 +02:00’  
DATETIMEOFFSET‘2006-12-25 01:01:00.0000000 -08:30’  

Note

A valid Entity SQL literal value can fall outside the supported ranges for CLR or the data source. This might result in an exception

Binary

A binary string literal is a sequence of hexadecimal digits delimited by single quotes following the keyword binary or the shortcut symbol X or x. The shortcut symbol X is case insensitive. A zero or more spaces are allowed between the keyword binary and the binary string value.

Hexadecimal characters are also case insensitive. If the literal is composed of an odd number of hexadecimal digits, the literal will be aligned to the next even hexadecimal digit by prefixing the literal with a hexadecimal zero digit. There is no formal limit on the size of the binary string.

Binary'00ffaabb'  
X'ABCabc'  
BINARY    '0f0f0f0F0F0F0F0F0F0F'  
X'' –- empty binary string  

Guid

A GUID literal represents a globally unique identifier. It is a sequence formed by the keyword GUID followed by hexadecimal digits in the form known as registry format: 8-4-4-4-12 enclosed in single quotes. Hexadecimal digits are case insensitive.

There can be any number of spaces between the GUID symbol and the literal payload, but no new lines.

Guid'1afc7f5c-ffa0-4741-81cf-f12eAAb822bf'  
GUID  '1AFC7F5C-FFA0-4741-81CF-F12EAAB822BF'  

See also

Null Literals and Type Inference (Entity SQL)

Null literals are compatible with any type in the Entity SQL type system. However, for the type of a null literal to be inferred correctly, Entity SQL imposes certain constraints on where a null literal can be used.

Typed Nulls

Typed nulls can be used anywhere. Type inference is not required for typed nulls because the type is known. For example, you can construct a null of type Int16 with the following Entity SQL construct:

(cast(null as Int16))

Free-Floating Null Literals

Free-floating null literals can be used in the following contexts:

  • As an argument to a CAST or TREAT expression. This is the recommended way to produce a typed null expression.

  • As an argument to a method or a function. Standard overload rules apply.

  • As one of the arguments to an arithmetic expression such as +, -, or /. The other arguments cannot be null literals, otherwise type inference is not possible.

  • As any of the arguments to a logical expression (AND, OR, or NOT). All the arguments are known to be of type Boolean.

  • As the argument to an IS NULL or IS NOT NULL expression.

  • As one or more of the arguments to a LIKE expression. All arguments are expected to be strings.

  • As one or more of the arguments to a named-type constructor.

  • As one or more of the arguments to a multiset constructor. At least one argument to the multiset constructor must be an expression that is not a null literal.

  • As one or more of the THEN or ELSE expressions in a CASE expression. At least one of the THEN or ELSE expressions in the CASE expression must be an expression other than a null literal.

Free-floating null literals cannot be used in other scenarios. For example, they cannot be used as arguments to a row constructor.

See also

Input Character Set (Entity SQL)

Entity SQL accepts UNICODE characters encoded in UTF-16.

String literals can contain any UTF-16 character enclosed in single quotes. For example, N'文字列リテラル'. When string literals are compared, the original UTF-16 values are used. For example, N'ABC' is different in Japanese and Latin codepages.

Comments can contain any UTF-16 character.

Escaped identifiers can contain any UTF-16 character enclosed in square brackets. For example, [エスケープされた識別子]. The comparison of UTF-16 escaped identifiers is case insensitive. Entity SQL treats versions of letters that appear the same but are from different code pages as different characters. For example, [ABC] is equivalent to [abc] if the corresponding characters are from the same code page. However, if the same two identifiers are from different code pages, they are not equivalent.

White space is any UTF-16 white space character.

A newline is any normalized UTF-16 newline character. For example, '\n' and '\r\n' are considered newline characters, but '\r' is not a newline character.

Keywords, expressions, and punctuation can be any UTF-16 character that normalizes to Latin. For example, SELECT in a Japanese codepage is a valid keyword.

Keywords, expressions, and punctuation can only be Latin characters. SELECT in a Japanese codepage is not a keyword. +, -, *, /, =, (, ), ‘, [, ] and any other language construct not quoted here can only be Latin characters.

Simple identifiers can only be Latin characters. This avoids ambiguity during comparison, because original values are compared. For example, ABC would be different in Japanese and Latin codepages.

See also

Query Expressions (Entity SQL)

A query expression combines many different query operators into a single syntax. Entity SQL provides various kinds of expressions, including the following: literals, parameters, variables, operators, functions, set operators, and so on. For more information, see Entity SQL Reference.

Clauses

A query expression is composed of a series of clauses that apply successive operations to a collection of objects. They are based on the same clauses found in standard a SQL select statement: SELECT, FROM, WHERE, GROUP BY, HAVING, and ORDER BY.

Scope

Names defined in the FROM clause are introduced into the FROM scope in order of appearance, left to right. In the JOIN list, expressions can refer to names defined earlier in the list. Public properties of elements identified in the FROM clause are not added to the FROM scope: They must be always referenced through the alias-qualified name. Normally, all parts of the select expression are considered within the FROM scope.

See also

Functions (Entity SQL)

Entity SQL supports user-defined functions, canonical functions, and provider-specific functions. User-defined functions are specified in the conceptual model or inline in the query. For more information, see User-Defined Functions.

Canonical functions are predefined in the Entity Framework and should be supported by data providers. Entity SQL commands will fail if a user calls a function that is not supported by a provider. Therefore, canonical functions are generally recommended over store-specific functions, which are in a provider-specific namespace. For more information, see Canonical Functions.

The Microsoft SQL Client Managed Provider provides a set of provider-specific functions. For more information, see SqlClient for Entity Framework Functions.

In This Section

User-Defined Functions

Function Overload Resolution

Aggregate Functions

See also

User-Defined Functions (Entity SQL)

Entity SQL supports calling user-defined functions in a query. You can define these functions inline with the query (see How to: Call a User-Defined Function) or as part of the conceptual model (see How to: Define Custom Functions in the Conceptual Model). Conceptual model functions are defined as an Entity SQL command in the DefiningExpression element of a Function element in the conceptual model.

Entity SQL enables you to define functions in the query command itself. The FUNCTION operator defines inline functions. You can define multiple functions in a single command, and these functions can have the same function name, as long as the function signatures are unique. For more information, see Function Overload Resolution.

See also

Function Overload Resolution (Entity SQL)

This topic describes how Entity SQL functions are resolved.

More than one function can be defined with the same name, as long as the functions have unique signatures.

When this is the case, the following criteria must be applied to determine which function is referenced by a given expression. These criteria are applied in sequence. The first criterion that applies only to a single function is the resolved function.

  1. Parameter number. The function has the same number of parameters specified in the expression.

  2. Exact match on type. Each argument type of the function exactly matches the parameter type, or is the null literal.

  3. Match on subtype. Each argument type of the function exactly matches or is a sub-type of the parameter type, or the argument is the null literal. In the event that several functions differ only in the number of sub-type conversions required, the function with the least number of sub-type conversions is the resolved function.

  4. Match on subtype or type promotion. Each argument type of the function exactly matches, is a sub-type of, or can be promoted to the parameter type, or the argument is the null literal. Again, in the event that several functions differ only in the number of sub-type conversions and promotions, the function with the least number of sub-type conversions and promotions is the resolved function.

If none of these criteria result in a single function being selected, the function invocation expression is ambiguous.

Even if a single function can be extracted using these rules, the arguments still might not match the parameters. An error is raised in this case.

For user-defined functions, the definition for an inline query function takes precedence even when a model-defined function exists with a signature that is a better match for the user-defined function.

See also

Aggregate Functions (Entity SQL)

An aggregate is a language construct that condenses a collection into a scalar as a part of a group operation. Entity SQL aggregates come in two forms:

  • Entity SQL collection functions that may be used anywhere in an expression. This includes using aggregate functions in projections and predicates that act on collections. Collection functions are the preferred mode of specifying aggregates in Entity SQL.

  • Group aggregates in query expressions that have a GROUP BY clause. As in Transact-SQL, group aggregates accept DISTINCT and ALL as modifiers to the aggregate input.

Entity SQL first tries to interpret an expression as a collection function and if the expression is in the context of a SELECT expression it interprets it as a group aggregate.

Entity SQL defines a special aggregate operator called GROUPPARTITION. This operator enables you to get a reference to the grouped input set. This allows more advanced grouping queries, where the results of the GROUP BY clause can be used in places other than group aggregate or collection functions.

Collection Functions

Collection functions operate on collections and return a scalar value. For example, if orders is a collection of all orders, you can calculate the earliest ship date with the following expression:

min(select value o.ShipDate from LOB.Orders as o)

Group Aggregates

Group aggregates are calculated over a group result as defined by the GROUP BY clause. The GROUP BY clause partitions data into groups. For each group in the result, the aggregate function is applied and a separate aggregate is calculated by using the elements in each group as inputs to the aggregate calculation. When a GROUP BY clause is used in a SELECT expression, only grouping expression names, aggregates, or constant expressions may be present in the projection, HAVING, or ORDER BY clause.

The following example calculates the average quantity ordered for each product.

select p, avg(ol.Quantity) from LOB.OrderLines as ol

group by ol.Product as p

It is possible to have a group aggregate without an explicit GROUP BY clause in the SELECT expression. All elements will be treated as a single group, equivalent to the case of specifying a grouping based on a constant.

select avg(ol.Quantity) from LOB.OrderLines as ol

select avg(ol.Quantity) from LOB.OrderLines as ol group by 1

Expressions used in the GROUP BY clause are evaluated by using the same name-resolution scope that would be visible to the WHERE clause expression.

See also

Operator Precedence (Entity SQL)

When an Entity SQL query has multiple operators, operator precedence determines the sequence in which the operations are performed. The order of execution can significantly affect the query result.

Operators have the precedence levels shown in the following table. An operator with a higher level is evaluated before an operator with a lower level.

Level Operation type Operator
1 Primary . , [] ()
2 Unary ! not
3 Multiplicative * / %
4 Additive + -
5 Ordering < > <= >=
6 Equality = != <>
7 Conditional AND and &&
8 Conditional OR or &#124;&#124;

When two operators in an expression have the same operator precedence level, they are evaluated left to right, based on their position in the query. For example, x+y-z is evaluated as (x+y)-z.

You can use parentheses to override the defined precedence of the operators in a query. Everything within parentheses is evaluated first to yield a single result before that result can be used by any operator outside the parentheses. For example, x+y*z multiplies y by z and then adds x, but (x+y)*z adds x to y and then multiplies the result by z.

See also

Paging (Entity SQL)

Physical paging can be performed by using the SKIP and LIMIT sub-clauses in the ORDER BY clause. To perform physical paging deterministically, you should use SKIP and LIMIT. If you only want to restrict the number of rows in the result in a non-deterministic way, you should use TOP. TOP and SKIP/LIMIT are mutually exclusive.

TOP Overview

The SELECT clause can have an optional TOP sub-clause following the optional ALL/DISTINCT modifier. The TOP sub-clause specifies that only the first set of rows will be returned from the query result. For more information, see TOP.

SKIP And LIMIT Overview

SKIP and LIMIT are part of the ORDER BY clause. If a SKIP expression sub-clause is present in a ORDER BY clause, the results will be sorted according to the sort specification and the result set will include row(s) starting from the next row immediately after the SKIP expression. For example, SKIP 5 will skip the first five rows and return from the sixth row forward. If a LIMIT expression sub-clause is present in an ORDER BY clause, the query will be sorted according to the sort specification and the resulting number of rows will be restricted by the LIMIT expression. For instance, LIMIT 5 will restrict the result set to five instances or rows. SKIP and LIMIT do not have to be used together; you can use just SKIP or just LIMIT with ORDER BY clause. For more information, see the following topics:

See also

Comparison Semantics (Entity SQL)

Performing any of the following Entity SQL operators involves comparison of type instances:

Explicit comparison

Equality operations:

  • =

  • !=

Ordering operations:

  • <

  • <=

  • >

  • >=

Nullability operations:

  • IS NULL

  • IS NOT NULL

Explicit distinction

Equality distinction:

  • DISTINCT

  • GROUP BY

Ordering distinction:

  • ORDER BY

Implicit distinction

Set operations and predicates (equality):

  • UNION

  • INTERSECT

  • EXCEPT

  • SET

  • OVERLAPS

Item predicates (equality):

  • IN

Supported Combinations

The following table shows all the supported combinations of comparison operators for each kind of type:

Type =

!=
GROUP BY

DISTINCT
UNION

INTERSECT

EXCEPT

SET

OVERLAPS
IN < <=

> >=
ORDER BY IS NULL

IS NOT NULL
Entity type Ref1 All properties2 All properties2 All properties2 Throw3 Throw3 Ref1
Complex type Throw3 Throw3 Throw3 Throw3 Throw3 Throw3 Throw3
Row All properties4 All properties4 All properties4 Throw3 Throw3 All properties4 Throw3
Primitive type Provider-specific Provider-specific Provider-specific Provider-specific Provider-specific Provider-specific Provider-specific
Multiset Throw3 Throw3 Throw3 Throw3 Throw3 Throw3 Throw3
Ref Yes5 Yes5 Yes5 Yes5 Throw Throw Yes5
Association

type
Throw3 Throw Throw Throw Throw3 Throw3 Throw3

1The references of the given entity type instances are implicitly compared, as shown in the following example:

SELECT p1, p2   
FROM AdventureWorksEntities.Product AS p1   
     JOIN AdventureWorksEntities.Product AS p2   
WHERE p1 != p2 OR p1 IS NULL  

An entity instance cannot be compared to an explicit reference. If this is attempted, an exception is thrown. For example, the following query will throw an exception:

SELECT p1, p2   
FROM AdventureWorksEntities.Product AS p1   
     JOIN AdventureWorksEntities.Product AS p2   
WHERE p1 != REF(p2)  

2Properties of complex types are flattened out before being sent to the store, so they become comparable (as long as all their properties are comparable). Also see 4.

3The Entity Framework runtime detects the unsupported case and throws a meaningful exception without engaging the provider/store.

4An attempt is made to compare all properties. If there is a property that is of a non-comparable type, such as text, ntext, or image, a server exception might be thrown.

5All individual elements of the references are compared (this includes the entity set name and all the key properties of the entity type).

See also

Composing Nested Entity SQL Queries

Entity SQL is a rich functional language. The building block of Entity SQL is an expression. Unlike conventional SQL, Entity SQL is not limited to a tabular result set: Entity SQL supports composing complex expressions that can have literals, parameters, or nested expressions. A value in the expression can be parameterized or composed of some other expression.

Nested Expressions

A nested expression can be placed anywhere a value of the type it returns is accepted. For example:

-- Returns a hierarchical collection of three elements at top-level.   
-- x must be passed in the parameter collection.  
ROW(@x, {@x}, {@x, 4, 5}, {@x, 7, 8, 9})  
  
-- Returns a hierarchical collection of one element at top-level.  
-- x must be passed in the parameter collection.  
{{{@x}}};  

A nested query can be placed in a projection clause. For example:

-- Returns a collection of rows where each row contains an Address entity.  
-- and a collection of references to its corresponding SalesOrderHeader entities.  
SELECT address, (SELECT DEREF(soh)   
                    FROM NAVIGATE(address, AdventureWorksModel.FK_SalesOrderHeader_Address_BillToAddressID) AS soh)   
                    AS salesOrderHeader FROM AdventureWorksEntities.Address AS address  

In Entity SQL, nested queries must always be enclosed in parentheses:

-- Pseudo-Entity SQL  
( SELECT …  
FROM … )  
UNION ALL  
( SELECT …  
FROM … );  

The following example demonstrates how to properly nest expressions in Entity SQL: How to: Order the Union of Two Queries.

Nested Queries in Projection

Nested queries in the project clause might get translated into Cartesian product queries on the server. In some backend servers, including SLQ Server, this can cause the TempDB table to get very large, which can adversely affect server performance.

The following is an example of such a query:

SELECT c, (SELECT c, (SELECT c FROM AdventureWorksModel.Vendor AS c  ) As Inner2 FROM AdventureWorksModel.JobCandidate AS c  ) As Inner1 FROM AdventureWorksModel.EmployeeDepartmentHistory AS c  

Ordering Nested Queries

In the Entity Framework, a nested expression can be placed anywhere in the query. Because Entity SQL allows great flexibility in writing queries, it is possible to write a query that contains an ordering of nested queries. However, the order of a nested query is not preserved.

-- The following query will order the results by last name.  
SELECT C1.FirstName, C1.LastName  
        FROM AdventureWorksModel.Contact as C1  
        ORDER BY C1.LastName  
-- In the following query, ordering of the nested query is ignored.  
SELECT C2.FirstName, C2.LastName  
    FROM (SELECT C1.FirstName, C1.LastName  
        FROM AdventureWorksModel.Contact as C1  
        ORDER BY C1.LastName) as C2  

See also

Nullable Structured Types (Entity SQL)

A null instance of a structured type is an instance that does not exist. This is different from an existing instance in which all properties have null values.

This topic describes the nullable structured types, including which types are nullable and which code patterns produce null instances of structured nullable types.

Kinds of Nullable Structured Types

There are three kinds of nullable structure types:

  • Row types.

  • Complex types.

  • Entity types.

Code Patterns that Produce Null Instances of Structured Types

The following scenarios produce null instances:

  • Shaping null as a structured type:

  • TREAT (NULL AS StructuredType)  
    
  • Upcasting of a base type to a derived type:

  • TREAT (BaseType AS DerivedType)  
    
  • Outer join on false condition:

    Collection1 LEFT OUTER JOIN Collection2  
    ON FalseCondition  
    

    --or

    Collection1 RIGHT OUTER JOIN Collection2  
    ON FalseCondition  
    

    --or

  • Collection1 FULL OUTER JOIN Collection2  
    ON FalseCondition  
    
  • Dereferencing a null reference:

  • DEREF(NullRef)  
    
  • Obtaining ANYELEMENT from an empty collection:

  • ANYELEMENT(EmptyCollection)  
    
  • Checking for null instances of structured types:

    C#
    ...  
    for (int i = 0; i < reader.FieldCount; i++)  
    {  
        if (reader.IsDBNull(i))  
        {  
            Console.WriteLine("[NULL]");  
        }  
        else  
        {  
            Console.WriteLine(reader.GetValue(i).ToString());  
        }  
    }  
    

See also

Entity SQL reference

This section contains Entity SQL reference articles. This article summarizes and groups the Entity SQL operators by category.

Arithmetic operators

Arithmetic operators perform mathematical operations on two expressions of one or more numeric data types. The following table lists the Entity SQL arithmetic operators:

Operator Use
+ (Add) Addition.
/ (Divide) Division.
% (Modulo) Returns the remainder of a division.
* (Multiply) Multiplication.
- (Negative) Negation.
- (Subtract) Subtraction.

Canonical functions

Canonical functions are supported by all data providers and can be used by all querying technologies. The following table lists the canonical functions:

Function Type
Aggregate Entity SQL Canonical Functions Discusses aggregate Entity SQL canonical functions.
Math Canonical Functions Discusses math Entity SQL canonical functions.
String Canonical Functions Discusses string Entity SQL canonical functions.
Date and Time Canonical Functions Discusses date and time Entity SQL canonical functions.
Bitwise Canonical Functions Discusses bitwise Entity SQL canonical functions.
Other Canonical Functions Discusses functions not classified as bitwise, date/time, string, math, or aggregate.

Comparison operators

Comparison operators are defined for the following types: Byte, Int16, Int32, Int64, Double, Single, Decimal, String, DateTime, Date, Time, DateTimeOffset. Implicit type promotion occurs for the operands before the comparison operator is applied. Comparison operators always yield Boolean values. When at least one of the operands is null, the result is null.

Equality and inequality are defined for any object type that has identity, such as the Boolean type. Non-primitive objects with identity are considered equal if they share the same identity. The following table lists the Entity SQL comparison operators:

Operator Description
= (Equals) Compares the equality of two expressions.
> (Greater Than) Compares two expressions to determine whether the left expression has a value greater than the right expression.
>= (Greater Than or Equal To) Compares two expressions to determine whether the left expression has a value greater than or equal to the right expression.
IS [NOT] NULL Determines if a query expression is null.
< (Less Than) Compares two expressions to determine whether the left expression has a value less than the right expression.
<= (Less Than or Equal To) Compares two expressions to determine whether the left expression has a value less than or equal to the right expression.
[NOT] BETWEEN Determines whether an expression results in a value in a specified range.
!= (Not Equal To) Compares two expressions to determine whether the left expression isn't equal to the right expression.
[NOT] LIKE Determines whether a specific character string matches a specified pattern.

Logical and case expression operators

Logical operators test for the truth of a condition. The CASE expression evaluates a set of Boolean expressions to determine the result. The following table lists the logical and CASE expression operators:

Operator Description
&& (Logical AND) Logical AND.