dotnet / dotnet/EntityFramework.Docs
Change the "Cross-context transaction (relational databases only)"
- Dominant language
- Mermaid
- Stars
- 1.7k
- Forks
- 2k
- Avg merge
- 7d 23h
- Merged PRs (30d)
- 16
Description
Moved from [aspnet/Docs#4220](https://github.com/aspnet/Docs/issues/4220). Filed by @Ciantic, pertaining to the following doc:
https://docs.microsoft.com/ef/core/saving/transactions
I propose to change the section "Cross-context transaction (relational databases only)".
Current approach as it now stands suggest to change the super class constructor signature of DbContext, this can be cumbersome since everyone who develops DbContext super classes need to change their constructors.
With my approach below it is not required to refactor your precious DbContexts which may be separated in different projects etc. The super classes of DbContext can be "regular" and have a DbContextOptions as a argument as in every other example. The trick is then to provide the connection to shared contexts using the regular `AddDbContext` configuration.
1. Create a simple DI class that wraps the shared connection e.g.
```C#
///
/// This allows to share a DbConnection within a scope, e.g. between DbContexts so they can perform transactions
///
public class DbContextConnectionConfiguration : IDisposable
{
private readonly DbConnection _dbConnection;
private readonly Action _configuration;
private readonly bool _dispose;
public DbContextConnectionConfiguration(DbConnection dbConnection, Action configuration, bool dispose = true)
{
_dbConnection = dbConnection;
_configuration = configuration;
_dispose = dispose;
}
public void Configure(DbContextOptionsBuilder optionsBuilder)
{
_configuration(_dbConnection, optionsBuilder);
}
public void Dispose()
{
if (_dispose) {
_dbConnection.Dispose();
}
}
}
```
Now only thing required is to inject this to `AddDbContext` calls in *Startup.cs*:
```C#
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped(t => new DbContextConnectionConfiguration(
new SqliteConnection(Configuration.GetConnectionString("Default")),
(c, o) => o.UseSqlite(c)
));
services.AddDbContext((s, o) =>
{
s.GetService().Configure(o);
});
services.AddDbContext((s, o) =>
{
s.GetService().Configure(o);
});
}
```
That's it, there is no need to refactor your DbContext's just to share a connection.
Contributor guide
Assessment
This issue has not been assessed yet.