Giorgi Entity Framework. Exceptions Handle Database Errors Easily When Working With Entity Framework Core. Supports SQL Server, Postgre Sql, Sqlite, Oracle and My Sql.
Giorgi/EntityFramework.Exceptions: Handle database errors easily when working with Entity Framework Core. Supports SQLServer, PostgreSQL, SQLite, Oracle and MySql. #
Excerpt #
Handle database errors easily when working with Entity Framework Core. Supports SQLServer, PostgreSQL, SQLite, Oracle and MySql. - Giorgi/EntityFramework.Exceptions
EntityFramework.Exceptions #
Handle database errors easily when working with Entity Framework Core. Supports SQLServer, PostgreSQL, SQLite, Oracle and MySql
Entity Framework Community Standup Live Show #
Nick Chapsas - The Smart Way to Handle EF Core Exceptions #
What does EntityFramework.Exceptions do? #
When using Entity Framework Core for data access all database exceptions are wrapped in DbUpdateException
. If you need to find whether the exception was caused by a unique constraint, value being too long or value missing for a required column you need to dig into the concrete DbException
subclass instance and check the error code to determine the exact cause.
EntityFramework.Exceptions simplifies this by handling all the database specific details and throwing different exceptions. All you have to do is to configure DbContext
by calling UseExceptionProcessor
and handle the exception(s) you need, such as UniqueConstraintException
, CannotInsertNullException
, MaxLengthExceededException
, NumericOverflowException
, or ReferenceConstraintException
.
In case of UniqueConstraintException
and ReferenceConstraintException
you can get the name of the associated constraint with ConstraintName
property. The ConstraintProperties
will contain the properties that are part of the constraint.
Warning
ConstraintName
and ConstraintProperties
will be populated only if the index is defined in the Entity Framework Model. These properties will not be populated if the index exists in the database but isn’t part of the model or if the index is added with
MigrationBuilder.Sql method.
Warning
ConstraintName
and ConstraintProperties
will not be populated when using SQLite.
All these exceptions inherit from DbUpdateException
for backwards compatibility.
How do I get started? #
First, install the package corresponding to your database:
dotnet add package EntityFrameworkCore.Exceptions.SqlServer
dotnet add package EntityFrameworkCore.Exceptions.MySql
dotnet add package EntityFrameworkCore.Exceptions.MySql.Pomelo
dotnet add package EntityFrameworkCore.Exceptions.PostgreSQL
dotnet add package EntityFrameworkCore.Exceptions.Sqlite
dotnet add package EntityFrameworkCore.Exceptions.Oracle
Next, in your DbContext OnConfiguring
method call UseExceptionProcessor
extension method:
class DemoContext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<ProductSale> ProductSale { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Product>().HasIndex(u => u.Name).IsUnique();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseExceptionProcessor();
}
}
You will now start getting different exception for different database error. For example, when a unique constraints fails you will get UniqueConstraintException
exception:
using (var demoContext = new DemoContext())
{
demoContext.Products.Add(new Product
{
Name = "demo",
Price = 10
});
demoContext.Products.Add(new Product
{
Name = "demo",
Price = 100
});
try
{
demoContext.SaveChanges();
}
catch (UniqueConstraintException e)
{
//Handle exception here
Console.WriteLine($"Unique constraint {e.ConstraintName} violated. Duplicate value for {e.ConstraintProperties[0]}");
}
}
Usage with DbContext pooling #
Instead of calling UseExceptionProcessor
in the OnConfiguring
method, add it where you add your DbContextPool
:
// Replace UseNpgsql with the sql flavor you're using
builder.Services.AddDbContextPool<DemoContext>(options => options
.UseNpgsql(config.GetConnectionString("DemoConnection"))
.UseExceptionProcessor());