This topic describes performance characteristics of Telerik OpenAccess ORM and provides some considerations to help improve the performance of Telerik OpenAccess ORM applications.
Profiling Your Application
The OpenAccess Profiler and Tuning Advisor makes it easy for developers to see how OpenAccess is working behind the scenes. You can see all SQL queries sent to the database server, and the LINQ statement that generated them. In addition, the profiler has a built in alert system that will notify about potential issues, and suggest resolutions. For more information, read here.
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 a LINQ query, the query may not be executed immediately. Query execution is deferred until the results are needed, such as a foreach (C#) or For Each (Visual Basic) enumeration or when it is assigned to fill a List collection. Query execution begins immediately when you call a LINQ method that returns a singleton query, such as First or Any. For more information, see Flow of Execution and Query Execution.
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.
Query and Mapping Complexity
The complexity of the individual queries and the mapping in the domain model will have a significant effect on query performance.
Domain models that are more complex than a simple one-to-one mapping between persistent classes in the conceptual model and tables in the storage model generate more complex commands than models that have a one-to-one mapping.
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 Telerik OpenAccess ORM translates a query against a domain model into an equivalent query against the data source. When a single persistent class in the domain model maps to more than one table in the data source, or when a relationship between persistent classes is mapped to a join table, the query command executed against the data source query may require one or more joins.
- Nested queries may create joins on the server and can return a large number of rows.
- Any query that returns 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 optimal query performance, you must define relationships between persistent classes both as associations in the domain model and as logical relationships in the data source.
When you call the SaveChanges method on an OpenAccessContext, 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.
Strategies for Improving Performance
You can improve the overall performance of queries in Telerik OpenAccess ORM by using the following strategies.
Return the correct amount of data
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 OpenAccessContext
In most cases, you should create an OpenAccessContext instance within an using statement. This can increase the performance by ensuring that the resources associated with the OpenAccessContext are disposed automatically when the code exits the statement block. However, when controls are bound to objects managed by the OpenAccessContext, the context instance should be maintained as long as the binding is needed and disposed off manually.