C# tutorials > Frameworks and Libraries > Entity Framework Core (EF Core) > Connecting to different database providers (SQL Server, PostgreSQL, MySQL, SQLite)

Connecting to different database providers (SQL Server, PostgreSQL, MySQL, SQLite)

Entity Framework Core (EF Core) is a powerful ORM (Object-Relational Mapper) that allows you to interact with various database systems using .NET. This tutorial will guide you through connecting to different database providers such as SQL Server, PostgreSQL, MySQL, and SQLite using EF Core. We'll cover the necessary NuGet packages, connection string configurations, and code examples to get you started.

Prerequisites

Before you begin, ensure you have the following:

  1. .NET SDK installed.
  2. A code editor such as Visual Studio or VS Code.
  3. Basic understanding of C# and EF Core concepts.

Creating a New Project

First, create a new console application using the .NET CLI.

dotnet new console -n EFCoreDatabaseConnections
cd EFCoreDatabaseConnections

Installing EF Core and Database Provider Packages

Next, add the necessary NuGet packages for EF Core and the specific database providers you want to use. Here, we're adding packages for SQL Server, PostgreSQL, MySQL, and SQLite. Install only the providers you plan to use in your project.

dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
dotnet add package Pomelo.EntityFrameworkCore.MySql
dotnet add package Microsoft.EntityFrameworkCore.Sqlite

Defining the Model

Define the data model. In this example, we create a simple Blog entity and a BloggingContext which derives from DbContext. The BloggingContext represents the database session and includes a DbSet<Blog> property that allows us to query and save Blog instances.

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

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

    public BloggingContext(DbContextOptions<BloggingContext> options) : base(options)
    {
    }
}

Configuring the Database Connection (SQL Server)

To connect to SQL Server, use the UseSqlServer method in the OnConfiguring method of your DbContext. Provide a valid connection string. Replace the connection string with your actual SQL Server connection details.

This configuration uses LocalDB, a lightweight version of SQL Server Express, and assumes you have it installed. The database name is EFCoreDatabaseConnections, and it uses integrated security.

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

Configuring the Database Connection (PostgreSQL)

To connect to PostgreSQL, use the UseNpgsql method. Replace yourpassword with your PostgreSQL user password. Ensure that PostgreSQL is installed and running.

You will need to install the Npgsql.EntityFrameworkCore.PostgreSQL NuGet package.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseNpgsql("Host=localhost;Database=EFCoreDatabaseConnections;Username=postgres;Password=yourpassword");
}

Configuring the Database Connection (MySQL)

To connect to MySQL, use the UseMySql method. Replace yourpassword with your MySQL user password and ensure you replace 8.0.30 with your actual MySQL server version. Ensure that MySQL is installed and running.

You will need to install the Pomelo.EntityFrameworkCore.MySql NuGet package.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseMySql("Server=localhost;Database=EFCoreDatabaseConnections;Uid=root;Pwd=yourpassword;", Microsoft.EntityFrameworkCore.ServerVersion.Parse("8.0.30"));
}

Configuring the Database Connection (SQLite)

To connect to SQLite, use the UseSqlite method. This will create a new SQLite database file named EFCoreDatabaseConnections.db in the project directory if it doesn't already exist.

No external database server is required for SQLite, making it easy to set up.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlite("Data Source=EFCoreDatabaseConnections.db");
}

Performing Database Operations

Here's an example of how to perform basic database operations (adding and retrieving data) using the BloggingContext. Note that the `options` parameter must be properly initialized using one of the `UseXXX` methods.

using (var context = new BloggingContext(options))
{
    context.Blogs.Add(new Blog { Url = "http://example.com" });
    context.SaveChanges();

    var blogs = context.Blogs.ToList();
    foreach (var blog in blogs)
    {
        Console.WriteLine(blog.Url);
    }
}

Complete Program.cs

This is a complete Program.cs file demonstrating how to configure and use EF Core with different database providers. Remember to uncomment only one of the database connection configurations at a time.

using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

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

    public BloggingContext(DbContextOptions<BloggingContext> options) : base(options)
    {
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // Choose ONE of the following configurations based on your database:

        // SQL Server
        // optionsBuilder.UseSqlServer("Server=(localdb)\mssqllocaldb;Database=EFCoreDatabaseConnections;Trusted_Connection=True;");

        // PostgreSQL
        // optionsBuilder.UseNpgsql("Host=localhost;Database=EFCoreDatabaseConnections;Username=postgres;Password=yourpassword");

        // MySQL
        // optionsBuilder.UseMySql("Server=localhost;Database=EFCoreDatabaseConnections;Uid=root;Pwd=yourpassword;", Microsoft.EntityFrameworkCore.ServerVersion.Parse("8.0.30"));

        // SQLite
         optionsBuilder.UseSqlite("Data Source=EFCoreDatabaseConnections.db");
    }
}

class Program
{
    static void Main(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();

        //Ensure you use the appropriate configuration within OnConfiguring method of BloggingContext.  

        using (var context = new BloggingContext(optionsBuilder.Options))
        {
            context.Database.EnsureCreated(); //Creates the Database if it doesn't already exist
            
            context.Blogs.Add(new Blog { Url = "http://example.com" });
            context.SaveChanges();

            var blogs = context.Blogs.ToList();
            foreach (var blog in blogs)
            {
                Console.WriteLine(blog.Url);
            }
        }
    }
}

Concepts Behind the Snippet

This snippet illustrates the core concept of using Entity Framework Core to abstract database interactions. EF Core uses providers that translate LINQ queries into SQL queries specific to each database system. The DbContext acts as a bridge between your .NET application and the database. The Connection String provides essential information on how to locate and authenticate against your target database.

Real-Life Use Case

Imagine building a social media platform. You might use SQL Server for user profiles and relational data, PostgreSQL for storing geographic data, MySQL for managing content like posts and comments, and SQLite for storing user-specific settings on a mobile app.

Best Practices

  • Connection String Security: Never hardcode sensitive connection strings directly in your code. Use configuration files or environment variables.
  • Database Context Lifetime: Use dependency injection to manage the lifetime of your DbContext. For web applications, a scoped lifetime is generally appropriate.
  • Error Handling: Implement robust error handling to gracefully handle database connection failures or data access exceptions.
  • Database Migrations: Use EF Core migrations to manage database schema changes over time. This helps ensure a smooth upgrade process.

Interview Tip

When discussing EF Core in interviews, highlight your understanding of database providers, connection string configurations, and the benefits of using an ORM for data access. Be prepared to discuss strategies for handling database-specific differences and the trade-offs involved in choosing different database systems.

When to Use Them

Use different database providers when your application requires specific database features (e.g., geospatial data in PostgreSQL) or when you need to support existing databases with specific architectures. SQLite is appropriate for small, local data storage needs.

Memory Footprint

The memory footprint varies significantly depending on the database provider and the complexity of the queries. SQLite generally has the smallest footprint, while SQL Server and PostgreSQL can require more resources, especially with large datasets and concurrent connections.

Alternatives

Alternatives to EF Core include Dapper (a micro-ORM), ADO.NET, and other ORMs like NHibernate. Dapper offers more control over SQL queries but requires more manual mapping of data.

Pros

  • Abstraction: Provides a high level of abstraction over database interactions.
  • Code-First Development: Supports code-first development, allowing you to define your database schema using C# classes.
  • LINQ Support: Enables querying data using LINQ, which is more readable and maintainable than raw SQL.
  • Cross-Platform: EF Core is cross-platform and can be used on Windows, Linux, and macOS.

Cons

  • Performance Overhead: ORMs can introduce performance overhead compared to raw SQL queries.
  • Complexity: Can be complex to configure and use effectively, especially for advanced scenarios.
  • SQL Generation: The generated SQL may not always be optimal, requiring manual tuning in some cases.

FAQ

  • How do I handle connection string security?

    Store connection strings in configuration files (e.g., appsettings.json) or environment variables and encrypt them if necessary. Avoid hardcoding them directly in your code.
  • Can I use different database providers in the same application?

    Yes, but it's generally not recommended unless you have a specific need. It can increase complexity and maintenance overhead.
  • How do I handle database migrations?

    Use the EF Core migration tools (dotnet ef migrations add, dotnet ef database update) to manage schema changes and ensure a smooth upgrade process.