European ASP.NET 4.5 Hosting BLOG

BLOG about ASP.NET 4, ASP.NET 4.5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

European ASP.NET Core 10.0 Hosting - HostForLIFE :: The Real Thought Process of the.NET Garbage Collector

clock March 30, 2026 08:01 by author Peter

One of the most important duties of any runtime environment is memory management. Unlike lower-level languages like C or C++, developers do not manually allocate and free memory in languages like C#. Rather, the trash collector manages memory automatically. Few developers comprehend how the garbage collector actually determines what to collect, when to collect it, and why some objects survive longer than others, even though the majority of developers are aware that it cleans useless items.

The Microsoft.NET platform has a very advanced garbage collector. It doesn't eliminate items at random. Rather, it employs a collection of clever heuristics and algorithms intended to maximize memory and speed. Developers can create more effective and memory-efficient apps by comprehending how the garbage collector "thinks."

What Is the .NET Garbage Collector?
The garbage collector is a component of the Common Language Runtime responsible for automatic memory management.

Its main responsibilities include:

  • Allocating memory for new objects
  • Tracking which objects are still in use
  • Reclaiming memory from unused objects
  • Compacting memory to reduce fragmentation

Instead of forcing developers to manually manage memory, the garbage collector continuously monitors object usage and cleans up memory when necessary.

The Core Philosophy of the Garbage Collector
The .NET garbage collector is based on an important assumption known as the generational hypothesis.

The idea behind this hypothesis is simple:
Most objects die young.

In real-world applications, many objects are created for temporary tasks such as:

  • Calculations
  • Method calls
  • Temporary data structures

These objects often become unused very quickly.

Instead of scanning the entire memory every time, the garbage collector organizes objects by age and focuses on cleaning younger objects more frequently.

The Generational Memory Model

The garbage collector divides managed memory into three main generations.

Generation 0 (Gen 0)
Generation 0 contains newly created objects.

Characteristics:

  • Short-lived objects
  • Frequent collections
  • Very fast cleanup

When memory fills in Gen 0, the garbage collector runs a Gen 0 collection to remove objects that are no longer referenced.

Most objects are cleaned up at this stage.

Generation 1 (Gen 1)

Generation 1 acts as a buffer zone between short-lived and long-lived objects.

Objects move to Gen 1 when they survive a Gen 0 collection.

Characteristics:

  • Medium lifetime
  • Less frequent collections
  • Acts as a filter for Gen 2


Generation 2 (Gen 2)
Generation 2 stores long-lived objects such as:

  • application-level data
  • caches
  • static objects
  • large data structures

Collections in Gen 2 are more expensive because the garbage collector must scan a larger portion of memory.
Because of this, Gen 2 collections occur less frequently.

How the Garbage Collector Decides to Run?

The garbage collector does not run continuously. Instead, it is triggered when certain conditions occur.

Some common triggers include:

1. Memory Allocation Threshold

When the runtime cannot allocate memory for a new object, the garbage collector starts a collection cycle.

2. System Memory Pressure
If the operating system reports low available memory, the garbage collector becomes more aggressive in reclaiming memory.

3. Explicit Requests

Developers can manually request a collection using:

GC.Collect();

However, forcing garbage collection is generally discouraged because it can reduce application performance.

How the Garbage Collector Finds Unused Objects?

The garbage collector uses a reachability analysis approach.
Instead of checking every object individually, it begins with a set of root references.

These roots include:

  • Static variables
  • Local variables on the stack
  • CPU registers
  • Active threads

From these roots, the garbage collector traces all reachable objects.
If an object cannot be reached from any root reference, it is considered garbage and becomes eligible for removal.
This process is called mark-and-sweep.

Memory Compaction

After removing unused objects, the garbage collector performs memory compaction.
This step moves remaining objects closer together to eliminate gaps in memory.

Benefits of compaction include:

  • Reduced memory fragmentation
  • Faster memory allocation
  • Improved cache performance

Memory compaction ensures that future allocations can occur efficiently.

The Large Object Heap
Objects larger than approximately 85 KB are stored in a special area known as the Large Object Heap (LOH).

The LOH behaves differently from the standard generational heaps.

Characteristics of LOH:

  • Used for large arrays and data structures
  • Collected only during Gen 2 collections
  • Historically not compacted frequently

Because of this, allocating many large objects repeatedly can lead to memory fragmentation.
Understanding how the LOH works helps developers design memory-efficient applications.

Background Garbage Collection
Modern versions of the .NET runtime support background garbage collection.
Instead of stopping the entire application while cleaning memory, the garbage collector performs many operations concurrently with application execution.
This reduces application pauses and improves responsiveness, particularly in server applications built with ASP.NET.

What Developers Should Learn From the GC

Understanding the garbage collector helps developers write better code.

Some key lessons include:
Avoid Creating Too Many Temporary Objects
Frequent object allocation increases pressure on Gen 0 collections.

Reuse Objects When Possible

Object pooling can reduce allocation overhead.

Be Careful With Large Objects

Large allocations can trigger expensive Gen 2 collections.

Avoid Unnecessary Object References

Keeping references alive longer than necessary prevents objects from being collected.

Common Misconceptions About Garbage Collection

Many developers misunderstand how the garbage collector works.

Misconception 1: Garbage Collection Runs Constantly

In reality, it runs only when necessary.

Misconception 2: Garbage Collection Always Improves Performance
While GC prevents memory leaks, excessive allocations can still harm performance.

Misconception 3: Developers Should Always Call GC.Collect()

Manual garbage collection is rarely beneficial and can disrupt the runtime’s optimization strategies.

Conclusion

The garbage collector in the Microsoft .NET ecosystem is not just a cleanup tool. It is an intelligent memory management system designed to optimize both performance and developer productivity. By organizing memory into generations, tracking object reachability, and reclaiming unused memory efficiently, the garbage collector ensures that applications written in C# can run reliably without manual memory management.

However, understanding how the garbage collector actually works allows developers to write more efficient code, reduce memory pressure, and build high-performance applications. In the end, the garbage collector is not magic it follows clear rules and strategies. The better developers understand those strategies, the better they can design applications that work with the runtime rather than against it.

HostForLIFE ASP.NET Core 10.0 Hosting

European Best, cheap and reliable ASP.NET Core 10.0 hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



European ASP.NET Core 10.0 Hosting - HostForLIFE :: How to Manage ASP.NET Core Web API Global Exception Handling?

clock March 26, 2026 09:28 by author Peter

Handling errors properly is one of the most important parts of building a robust ASP.NET Core Web API. If exceptions are not handled correctly, your application may crash, expose sensitive data, or provide a poor user experience. Global exception handling allows you to manage all errors in one place instead of writing try-catch blocks in every controller or service. This makes your code cleaner, easier to maintain, and more secure.

In this article, you will learn how to implement global exception handling in ASP.NET Core Web API step by step using simple language and real-world examples.

What is Global Exception Handling?
Global exception handling is a centralized way to catch and handle all runtime errors (exceptions) in your application.

Instead of writing this everywhere:
try
{
    // logic
}
catch(Exception ex)
{
    // handle error
}


You define a single place that handles all exceptions automatically.

Benefits:

  • Cleaner code (no repetitive try-catch)
  • Better error management
  • Consistent API responses
  • Improved security

Types of Exceptions in ASP.NET Core
Common types of exceptions you may encounter:

  • System exceptions (NullReferenceException, DivideByZeroException)
  • Custom exceptions (business logic errors)
  • Validation errors
  • Unauthorized access errors

Understanding these helps you handle them properly.

Approach 1: Using Built-in Exception Handling Middleware

ASP.NET Core provides a built-in middleware to handle global exceptions.

Step 1: Configure Exception Handling in Program.cs

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/error");
}


This redirects all exceptions to a specific endpoint.

Step 2: Create Error Controller

using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;


[ApiController]
public class ErrorController : ControllerBase
{
    [Route("/error")]
    public IActionResult HandleError()
    {
        var context = HttpContext.Features.Get<IExceptionHandlerFeature>();
        var exception = context?.Error;

        return Problem(
            detail: exception?.Message,
            title: "An error occurred",
            statusCode: 500
        );
    }
}

This ensures a consistent response format.

Approach 2: Custom Middleware for Global Exception Handling

This is the most recommended and flexible approach.

Step 1: Create Custom Middleware


Create a new file: ExceptionMiddleware.cs
using System.Net;
using System.Text.Json;

public class ExceptionMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<ExceptionMiddleware> _logger;

    public ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Unhandled Exception");
            await HandleExceptionAsync(context, ex);
        }
    }

    private static Task HandleExceptionAsync(HttpContext context, Exception exception)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

        var response = new
        {
            StatusCode = context.Response.StatusCode,
            Message = "Something went wrong",
            Detailed = exception.Message
        };

        return context.Response.WriteAsync(JsonSerializer.Serialize(response));
    }
}

Step 2: Register Middleware in Program.cs
app.UseMiddleware<ExceptionMiddleware>();

Place it early in the pipeline (before other middlewares).

Handling Different Exception Types

You can customize responses based on exception types.

Example:
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
{
    HttpStatusCode status;
    string message;

    switch (exception)
    {
        case UnauthorizedAccessException:
            status = HttpStatusCode.Unauthorized;
            message = "Unauthorized access";
            break;

        case ArgumentException:
            status = HttpStatusCode.BadRequest;
            message = "Invalid request";
            break;

        default:
            status = HttpStatusCode.InternalServerError;
            message = "Server error";
            break;
    }

    context.Response.StatusCode = (int)status;

    var result = JsonSerializer.Serialize(new
    {
        StatusCode = context.Response.StatusCode,
        Message = message
    });

    return context.Response.WriteAsync(result);
}


Creating Custom Exceptions
Custom exceptions help represent business logic errors.
public class NotFoundException : Exception
{
    public NotFoundException(string message) : base(message) { }
}


Usage:
if (user == null)
{
    throw new NotFoundException("User not found");
}


Handle it in middleware for better responses.

Standard API Error Response Format
Use a consistent structure:
{
  "statusCode": 500,
  "message": "Error message",
  "details": "Optional details"
}


This improves frontend integration.

Logging Exceptions

Logging is critical for debugging and monitoring.

ASP.NET Core provides built-in logging:
_logger.LogError(exception, "Error occurred");


You can also integrate tools like:

  • Serilog
  • NLog
  • Application Insights

Best Practices for Global Exception Handling

  • Do not expose sensitive details in production
  • Use structured logging
  • Handle known exceptions separately
  • Return proper HTTP status codes
  • Keep response format consistent

Common Mistakes to Avoid

  • Using try-catch everywhere
  • Returning raw exception messages
  • Not logging errors
  • Incorrect status codes

Real-World Example Flow

  • Client sends request
  • API processes request
  • Exception occurs
  • Middleware catches exception
  • Logs error
  • Returns standardized JSON response

When to Use Global Exception Handling
Use it in:

  • REST APIs
  • Microservices
  • Enterprise applications

It ensures reliability and maintainability.

Summary
Global exception handling in ASP.NET Core Web API helps you manage all errors in a centralized way. By using built-in middleware or creating custom middleware, you can ensure consistent error responses, better logging, and improved application security. This approach reduces code duplication and makes your application more professional and production-ready.

HostForLIFE ASP.NET Core 10.0 Hosting

European Best, cheap and reliable ASP.NET Core 10.0 hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



European ASP.NET Core 10.0 Hosting - HostForLIFE :: How to Resolve the ASP.NET Varchar to Datetime Conversion Error?

clock March 11, 2026 09:01 by author Peter

The "The conversion of a varchar data type to a datetime data type resulted in an out-of-range value" error is a frequent problem that developers run into while working with ASP.NET apps that communicate with SQL Server. We'll talk about the causes, short-term fixes, and long-term solutions.

Overview
Date and time values are frequently required when an ASP.NET application puts data into a SQL Server database. One frequent problem occurs when attempting to pass a DateTime value as a string, which SQL Server is unable to properly read because of regional variations in date formatting. When attempting to insert DateTime, this problem usually results in the "out-of-range" error.now entered into the database as a string.

The best solution 'parameterized queries' will be presented in this post after a thorough discussion of the issue and a walkthrough of a temporary patch. This method enhances the security and maintainability of your code in addition to fixing the mistake.

The Issue: Problems with DateTime Formatting
A particular format is required by SQL Server when data, particularly DateTime values, are put into a database. An out-of-range error may occur if SQL Server is unable to properly parse the DateTime value if it is supplied as a string in an unusual format.

Here is an illustration of a situation:
The code in an ASP.NET application may dynamically construct a SQL query to add information to the ContactInfo database, which contains a DateTime field:

str1 = "insert into ContactInfo(FirstName, LastName, MobileNo, Email, Country, State, City, APIType, AppName, Reason, ReasonComment, Message, CompanyName, ContactPerson, usertype, indCompanyName, date)";

str1 += " values('-', '-', '" + Contact1.Text + "', '" +
        Email.Text.Replace(" ", "") + "', '" +
        drpCountry.SelectedItem.Text + "', '" +
        state + "', '" +
        city + "', '" +
        Assestlist + "', '" +
        SiteName.Text.Replace("'", "_") + "', '" +
        drpApi.SelectedValue + "', '" +
        usercomment.Replace("'", "_") + "', '" +
        txtMessage.Text.Replace("'", "_") + "', '" +
        Fname.Text.Replace(" ", "") + "', '" +
        Lname.Text.Replace(" ", "") + "', '" +
        usertype + "', '" +
        infocompany.Text + "', '" +
        DateTime.Now + "')";


In this code, DateTime.Now is concatenated directly into the SQL query. When DateTime.Now is converted to a string, it might be formatted in a way that SQL Server cannot interpret correctly, such as:
13-01-2026 10:25:40

SQL Server may expect the DateTime to be in an ISO-compliant format like:
2026-01-13 10:25:40

If the format does not match, SQL Server may throw the out-of-range error.

Temporary Fix: Use ISO 8601 Format

The quickest way to fix this issue is to format the DateTime value as an ISO-compliant string before passing it to SQL Server. This ensures that SQL Server always understands the date format, regardless of the regional settings on the server.

Modify the code like this:
string sqlDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

str1 += " values('-', '-', '" + Contact1.Text + "', '" +
        Email.Text.Replace(" ", "") + "', '" +
        drpCountry.SelectedItem.Text + "', '" +
        state + "', '" +
        city + "', '" +
        Assestlist + "', '" +
        SiteName.Text.Replace("'", "_") + "', '" +
        drpApi.SelectedValue + "', '" +
        usercomment.Replace("'", "_") + "', '" +
        txtMessage.Text.Replace("'", "_") + "', '" +
        Fname.Text.Replace(" ", "") + "', '" +
        Lname.Text.Replace(" ", "") + "', '" +
        usertype + "', '" +
        infocompany.Text + "', '" +
        sqlDate + "')";


By using DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), the date is formatted in a universally accepted ISO 8601 format, which SQL Server will always understand. While this works as a temporary fix, it’s not the most robust or maintainable solution.

The Long-Term Solution: Use Parameterized Queries

Although formatting the DateTime value as a string resolves the issue temporarily, the best solution is to use parameterized queries. Parameterized queries not only eliminate date conversion issues but also improve security and prevent SQL injection attacks.

Here’s how to refactor the code to use parameterized queries:
string query = @"insert into ContactInfo
(FirstName, LastName, MobileNo, Email, Country, State, City,
 APIType, AppName, Reason, ReasonComment, Message,
 CompanyName, ContactPerson, usertype, indCompanyName, date)
values
('-', '-', @MobileNo, @Email, @Country, @State, @City,
 @APIType, @AppName, @Reason, @ReasonComment, @Message,
 @CompanyName, @ContactPerson, @usertype, @indCompanyName, @date)";


Now, create the parameters:
SqlParameter[] param =
{
    new SqlParameter("@MobileNo", Contact1.Text),
    new SqlParameter("@Email", Email.Text.Replace(" ", "")),
    new SqlParameter("@Country", drpCountry.SelectedItem.Text),
    new SqlParameter("@State", state),
    new SqlParameter("@City", city),
    new SqlParameter("@APIType", Assestlist),
    new SqlParameter("@AppName", SiteName.Text),
    new SqlParameter("@Reason", drpApi.SelectedValue),
    new SqlParameter("@ReasonComment", usercomment),
    new SqlParameter("@Message", txtMessage.Text),
    new SqlParameter("@CompanyName", Fname.Text),
    new SqlParameter("@ContactPerson", Lname.Text),
    new SqlParameter("@usertype", usertype),
    new SqlParameter("@indCompanyName", infocompany.Text),
    new SqlParameter("@date", SqlDbType.DateTime) { Value = DateTime.Now }
};

SqlHelper.ExecuteNonQuery(SQL, CommandType.Text, query, param);


Explanation of Parameterized Queries
Avoids String Concatenation: Using parameters means we no longer have to manually concatenate user inputs or DateTime values into the query string. This approach helps prevent errors and SQL injection attacks.

SQL Parameters: We pass the DateTime.Now value as a parameter with the correct type (SqlDbType.DateTime). SQL Server handles the conversion, ensuring it is always in the correct format.

Prevents SQL Injection: By using parameters, we avoid manually building the query string, which protects the application from SQL injection attacks.

Conclusion
The "The conversion of a varchar data type to a datetime data type resulted in an out-of-range value" error occurs when SQL Server attempts to convert a string (often from DateTime.Now) into a DateTime value, and the format is not understood. The most straightforward fix is to format the date as an ISO-compliant string. However, the best practice is to use parameterized queries, which not only resolve the issue but also enhance security, maintainability, and performance.

Summary

  • Temporary fix: Format DateTime as yyyy-MM-dd HH:mm:ss.
  • Long-term solution: Use parameterized queries to prevent errors and SQL injection.

This approach ensures that your application works reliably across different environments and is easier to maintain in the long run.

HostForLIFE ASP.NET Core 10.0 Hosting

European Best, cheap and reliable ASP.NET Core 10.0 hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



European ASP.NET Core 10.0 Hosting - HostForLIFE :: Various ASP.NET Database Provider Types The Core

clock March 2, 2026 09:03 by author Peter

Selecting the best database provider for ASP.NET Core enterprise-grade apps has a direct impact on performance, scalability, maintainability, and cloud strategy. It's not merely a technical choice.

With the help of actual coding examples, we will examine the many kinds of database providers that are available in ASP.NET Core, their internal operations, how to select the best database provider, and when to use each.

1. Comprehending ASP.NET Core Database Providers
A database is not directly communicated with by ASP.NET Core. Rather, it depends on:

  • ADO.NET providers
  • Entity Framework Core database providers
  • Micro-ORM providers (like Dapper)
  • NoSQL SDK providers
  • In-memory providers for testing
  • The abstraction layer allows you to switch providers without rewriting your business logic.
  • The most common abstraction used today is Entity Framework Core (EF Core).

2. Entity Framework Core Relational Providers
EF Core supports multiple relational database engines through pluggable providers.

2.1 SQL Server Provider

Package:
Microsoft.EntityFrameworkCore.SqlServer

Best for:

  • Enterprise systems
  • Azure-hosted apps
  • Microsoft ecosystem environments


Setup Example
Install package:
dotnet add package Microsoft.EntityFrameworkCore.SqlServer

Register in Program.cs:
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(
    builder.Configuration.GetConnectionString("DefaultConnection")));

Connection string (appsettings.json):
"ConnectionStrings": {
  "DefaultConnection": "Server=.;Database=AppDb;Trusted_Connection=True;"
}

Production scenario:

  • Banking systems
  • ERP systems
  • Applications using SQL Server Always On

2.2 PostgreSQL Provider
Package:
Npgsql.EntityFrameworkCore.PostgreSQL

Best for:

  • Linux deployments
  • Cloud-native systems
  • Cost-optimized production environments

Setup Example
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
    builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseNpgsql(
        builder.Configuration.GetConnectionString("PostgresConnection")));

Connection string:
"PostgresConnection": "Host=localhost;Database=AppDb;Username=postgres;Password=pass"

Real-world use case:

  • SaaS multi-tenant platforms
  • Kubernetes deployments

2.3 MySQL / MariaDB Provider
Package:
Pomelo.EntityFrameworkCore.MySql

Setup:
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseMySql(
        builder.Configuration.GetConnectionString("MySqlConnection"),
        ServerVersion.AutoDetect(
            builder.Configuration.GetConnectionString("MySqlConnection"))));

Best for:

  • Hosting providers
  • PHP-to-.NET migration projects

2.4 SQLite Provider
Package:
Microsoft.EntityFrameworkCore.Sqlite

Use cases:

  • Desktop apps
  • Mobile apps
  • Lightweight internal tools

Example:
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlite("Data Source=app.db"));

Common in:

  • Proof of Concepts
  • Edge deployments

3. In-Memory Provider (Testing)
Package:
Microsoft.EntityFrameworkCore.InMemory

Important: Not a real relational database.
Used for:

  • Unit testing
  • Integration testing

Example:
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseInMemoryDatabase("TestDb"));

Example test:
[Fact]
public void AddUser_ShouldSaveUser()
{
    var options = new DbContextOptionsBuilder<AppDbContext>()
        .UseInMemoryDatabase("TestDb")
        .Options;

    using var context = new AppDbContext(options);
    context.Users.Add(new User { Name = "John" });
    context.SaveChanges();

    Assert.Equal(1, context.Users.Count());
}


Tip: Use SQLite in-memory mode instead for realistic relational behavior.

4. NoSQL Database Providers
ASP.NET Core also supports NoSQL databases via dedicated SDKs.

4.1 MongoDB
Package:
MongoDB.Driver

Setup:
builder.Services.AddSingleton<IMongoClient>(
new MongoClient(builder.Configuration["MongoSettings:Connection"]));

Repository example:
public class UserRepository
{
    private readonly IMongoCollection<User> _collection;

    public UserRepository(IMongoClient client)
    {
        var database = client.GetDatabase("AppDb");
        _collection = database.GetCollection<User>("Users");
    }

    public async Task CreateAsync(User user)
    {
        await _collection.InsertOneAsync(user);
    }
}


Use cases:

  • Event-driven systems
  • High write throughput
  • Flexible schema applications

4.2 Azure Cosmos DB
Provider:
Microsoft.EntityFrameworkCore.Cosmos

Setup:
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseCosmos(
        builder.Configuration["Cosmos:AccountEndpoint"],
        builder.Configuration["Cosmos:AccountKey"],
        databaseName: "AppDb"));

Best for:

  • Globally distributed apps
  • Multi-region SaaS

5. Micro-ORM Providers (Dapper)
Sometimes EF Core is overkill.
Dapper works directly on ADO.NET providers.

Install:
dotnet add package Dapper

Example:
using (var connection = new SqlConnection(connectionString))
{
    var users = await connection.QueryAsync<User>(
        "SELECT * FROM Users WHERE IsActive = @IsActive",
        new { IsActive = true });
}

Use cases:

  • High-performance APIs
  • Read-heavy services
  • Reporting microservices

6. ADO.NET Native Providers
Low-level database access.

Example with SQL Server:
using SqlConnection connection = new SqlConnection(connectionString);
await connection.OpenAsync();

SqlCommand command = new SqlCommand(
    "SELECT COUNT(*) FROM Users", connection);

int count = (int)await command.ExecuteScalarAsync();

Best for:

  • Extreme performance scenarios
  • Legacy migrations

7. Switching Providers Without Changing Business Logic
One of EF Core’s biggest strengths is provider abstraction.

Example:
Change:
options.UseSqlServer(...)

To:
options.UseNpgsql(...)

If your code avoids provider-specific features, everything works without changes.

Advice: Avoid raw SQL that ties you to one engine unless necessary.

8. How to Choose the Right Provider
Consider:

Hosting environment (Azure, AWS, on-prem)

  • Licensing cost
  • Team expertise
  • Scalability requirements
  • Transaction complexity
  • Reporting needs
  • Cloud-native architecture

Enterprise rule of thumb:

  • Traditional enterprise system → SQL Server
  • Open-source cloud-native → PostgreSQL
  • Document-driven → MongoDB
  • Globally distributed → Cosmos DB
  • High-performance microservice → Dapper

9. Production Best Practices

  • Always use connection pooling
  • Enable retry policies
  • Use migrations responsibly
  • Monitor slow queries
  • Avoid N+1 problems
  • Use async methods
  • Configure proper indexing

Example enabling retry logic:
options.UseSqlServer(connectionString,
    sqlOptions => sqlOptions.EnableRetryOnFailure());


Key Takeaways

Database providers in ASP.NET Core are not just interchangeable components — they define how your system scales, performs, and evolves.

The power of ASP.NET Core lies in its provider abstraction model. You can build your domain logic once and swap infrastructure as needed.

As architects and senior developers, our responsibility is not just to make it work — but to make it scalable, testable, and future-ready.

If you’d like, I can also write a follow-up deep dive on:

  • EF Core performance tuning
  • Multi-database architecture
  • Read/write splitting
  • Multi-tenant database strategies
  • Hybrid relational + NoSQL systems

Happy Coding!

I write about modern C#, .NET, and real-world development practices. Follow me on C# Corner for regular insights, tips, and deep dives.

HostForLIFE ASP.NET Core 10.0 Hosting

European Best, cheap and reliable ASP.NET Core 10.0 hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



About HostForLIFE

HostForLIFE is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2019 Hosting, ASP.NET 5 Hosting, ASP.NET MVC 6 Hosting and SQL 2019 Hosting.


Month List

Tag cloud

Sign in