C# tutorials > Language Integrated Query (LINQ) > LINQ to Entities (Entity Framework Core) > Using LINQ with stored procedures
Using LINQ with stored procedures
Using LINQ with Stored Procedures in Entity Framework Core
This tutorial explores how to integrate LINQ (Language Integrated Query) with stored procedures using Entity Framework Core (EF Core). Stored procedures provide a way to encapsulate database logic and improve performance. Combining them with LINQ allows you to leverage the power of LINQ's query syntax and EF Core's object-relational mapping capabilities.
Introduction
Entity Framework Core allows you to execute stored procedures and map the results to entities or simple types. This approach offers flexibility when dealing with complex database operations or when you want to take advantage of pre-optimized stored procedures. We'll cover different ways to call stored procedures using EF Core and LINQ.
Setting up the Database Context
First, define your database context. This context represents a session with the database and allows you to query and save data. Ensure your context includes DbSet
properties for the entities you want to interact with. Replace Blog
and Post
with your actual entity classes.
public class BloggingContext : DbContext
{
public BloggingContext(DbContextOptions<BloggingContext> options) : base(options) { }
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>().ToTable("Blogs");
modelBuilder.Entity<Post>().ToTable("Posts");
}
}
Defining Entities
Define the entities that represent your database tables. These entities will be used to map the results from the stored procedures. Ensure that the properties in the entities match the columns returned by the stored procedure.
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
Calling a Stored Procedure with FromSqlRaw
The FromSqlRaw
method allows you to execute raw SQL queries, including stored procedures. It returns an IQueryable
of the specified entity type. Replace GetBlogsByUrl
with the actual name of your stored procedure and {0}
with the parameter placeholder. The ToList()
method executes the query and returns the results as a list of Blog
objects.
using Microsoft.EntityFrameworkCore;
// Example: Getting blogs by URL using a stored procedure
public List<Blog> GetBlogsByUrl(string url)
{
using (var context = new BloggingContext(options))
{
return context.Blogs.FromSqlRaw("EXECUTE GetBlogsByUrl {0}", url).ToList();
}
}
Calling a Stored Procedure with Parameters
You can pass multiple parameters to the stored procedure using placeholders. Ensure the order of the parameters in the FromSqlRaw
method matches the order of the parameters in the stored procedure definition. Replace GetPostsByBlogIdAndTitle
with the actual name of your stored procedure. The {0}
and {1}
are placeholders for blogId
and title
respectively.
// Example: Passing multiple parameters
public List<Post> GetPostsByBlogIdAndTitle(int blogId, string title)
{
using (var context = new BloggingContext(options))
{
return context.Posts.FromSqlRaw("EXECUTE GetPostsByBlogIdAndTitle {0}, {1}", blogId, title).ToList();
}
}
Mapping Results to a Different Entity
If the stored procedure returns a different structure than your existing entities, you can define a new class to map the results. Create a DbSet
for the new class using context.Set
and then use FromSqlRaw
to execute the stored procedure. This allows you to work with the results in a type-safe manner.
// Suppose the stored procedure returns a different structure
public class BlogSummary
{
public int BlogId { get; set; }
public string Url { get; set; }
public int PostCount { get; set; }
}
//Calling the stored procedure
public List<BlogSummary> GetBlogSummaries()
{
using (var context = new BloggingContext(options))
{
return context.Set<BlogSummary>().FromSqlRaw("EXECUTE GetBlogSummaries").ToList();
}
}
Executing Stored Procedures for Non-Query Operations
For stored procedures that perform non-query operations, such as inserting, updating, or deleting data, you can use the ExecuteSqlRaw
method. This method executes the SQL command and returns the number of rows affected. In this example, `InsertBlog` is a stored procedure that inserts a new blog into the database.
// Example: Inserting a new blog using a stored procedure
public void InsertBlog(string url)
{
using (var context = new BloggingContext(options))
{
context.Database.ExecuteSqlRaw("EXECUTE InsertBlog {0}", url);
}
}
Concepts Behind the Snippet
The core concept is leveraging the power of stored procedures for specific database operations while integrating them seamlessly within your EF Core application. FromSqlRaw
and ExecuteSqlRaw
are the key methods for executing stored procedures. Mapping the results to entities allows you to work with the data in a type-safe and object-oriented manner.
Real-Life Use Case
Imagine a scenario where you need to generate complex reports based on aggregated data. Instead of performing complex calculations in your application code, you can create a stored procedure that handles the aggregation logic and returns the results. Your application can then call this stored procedure using EF Core and display the report to the user. Another case would be for importing data from another system, applying data validation and complex business rules using stored procedures to guarantee data consistency and integrity.
Best Practices
Interview Tip
Be prepared to discuss the benefits and drawbacks of using stored procedures with EF Core. Highlight the performance advantages of stored procedures and the importance of using parameterized queries to prevent SQL injection. Also, be ready to explain how to map the results of stored procedures to entities or simple types.
When to Use Them
Use stored procedures when you need to perform complex database operations, improve performance, or encapsulate database logic. They are also useful for enforcing data integrity and security. Consider using them if the logic is better placed in the database tier and accessible by multiple applications, preventing code duplication across different clients.
Memory Footprint
Using stored procedures can potentially reduce the memory footprint on the application server, as the database server handles the complex calculations and data manipulation. The application server only receives the final results, minimizing the amount of data transferred and processed in the application's memory. However, this depends on how the stored procedure and the equivalent LINQ query are written and optimized.
Alternatives
Instead of stored procedures, you could perform all the data manipulation and calculations directly within your C# code using LINQ. You could also use database views to simplify complex queries. Another alternative is to use more advanced features of EF Core, like compiled queries, to optimize LINQ queries.
Pros
Cons
FAQ
-
How do I pass parameters to a stored procedure using EF Core?
You can pass parameters to a stored procedure using placeholders in the SQL query and providing the parameter values as arguments to theFromSqlRaw
orExecuteSqlRaw
methods. -
How do I map the results of a stored procedure to an entity?
You can use theFromSqlRaw
method and specify the entity type as the return type. EF Core will automatically map the results to the entity properties. -
Can I use LINQ to filter the results of a stored procedure?
Yes, you can use LINQ to filter the results of a stored procedure by chaining LINQ operators after theFromSqlRaw
method.