Introduction to Entity Framework Core Querying

Entity Framework Core (EF Core) is a modern, cross-platform, extensible version of the popular Object-Relational Mapper (ORM) for .NET. It allows developers to work with databases using .NET objects and LINQ (Language Integrated Query), abstracting away much of the underlying SQL generation. This introduction will guide you through the fundamental concepts of querying data with EF Core.

Core Concepts of EF Core Querying

At the heart of EF Core querying is the DbContext. The DbContext represents a session with the database and can be used to query and save data. Each entity type you want to query from the database must be represented as a DbSet<TEntity> property on your context.

The DbContext

A typical DbContext definition looks like this:


using Microsoft.EntityFrameworkCore;

public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=EFCoreQuerying;Trusted_Connection=True;");
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    public virtual ICollection<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 virtual Blog Blog { get; set; }
}
                    

Querying Data with LINQ to Entities

Once you have your DbContext configured, you can query data using LINQ. EF Core translates your LINQ queries into SQL commands that are executed against the database.

Retrieving All Data

To retrieve all blogs from the database:


using var context = new BloggingContext();
var allBlogs = context.Blogs.ToList();

foreach (var blog in allBlogs)
{
    Console.WriteLine($"- {blog.Url}");
}
                    

The ToList() method executes the query and materializes the results into a list of Blog objects.

Filtering Data

You can use LINQ's `Where` clause to filter results. For example, to find blogs with a URL containing "microsoft.com":


var microsoftBlogs = context.Blogs
                          .Where(b => b.Url.Contains("microsoft.com"))
                          .ToList();

foreach (var blog in microsoftBlogs)
{
    Console.WriteLine($"- {blog.Url}");
}
                    

Projecting Data

Sometimes you only need specific properties from an entity. You can use LINQ's `Select` clause for this, which is more efficient as it only retrieves the requested columns.


var blogUrls = context.Blogs
                      .Select(b => b.Url)
                      .ToList();

foreach (var url in blogUrls)
{
    Console.WriteLine($"- {url}");
}
                    

Understanding Query Execution

EF Core queries are typically deferred execution. This means the LINQ query isn't translated into SQL and executed until you materialize the results, for example, by calling ToList(), FirstOrDefault(), or iterating over the queryable. This allows you to build up complex queries step by step.

Immediate Execution

Methods like ToList(), ToArray(), FirstOrDefault(), Count(), and Any() trigger immediate execution.

Deferred Execution Example


var query = context.Blogs.Where(b => b.BlogId > 10); // Query is defined but not executed yet

// At this point, SQL is not generated or sent to the database.

var blogs = query.ToList(); // Now the query is executed.

Console.WriteLine($"Found {blogs.Count} blogs.");
                    

Conclusion

This introduction covers the basics of querying with EF Core, from setting up your DbContext to using LINQ to retrieve, filter, and project data. As you progress, you'll explore more advanced topics like navigation properties, eager, lazy, and explicit loading, and complex query patterns.

Continue to the next section to learn about Advanced EF Core Querying Techniques.