Я определенно не рекомендую глубокое клонирование по нескольким причинам, одна из которых заключается в том, что вам нужно будет выяснить множество внутренних компонентов EF, чтобы все исправить, а внутренние компоненты могут измениться (и вам нужно будет потратить на это некоторое время. ).
Второй вариант - это просто создание вашего контекста вручную, против чего я бы рекомендовал также, потому что современная инфраструктура использует DbContext
пул.
Итак, что вы можете зарегистрировать Func<DbContext>
(или создайте свою собственную фабрику) следующим образом:
services.AddSingleton<Func<DbContext>>(provider => () =>
{
var scope = provider.CreateScope();
return scope.ServiceProvider.GetRequiredService<DbContext>();
});
проблема здесь в том, что область действия здесь не будет удалена, и вы не можете (если у вас есть область действия по умолчанию для вашего DbContext
) разместить область внутри Func
, потому что ваш контекст также будет удален. Итак, вы можете попробовать создать какую-то одноразовую оболочку, чтобы вы могли вручную избавиться от всего следующим образом:
public class DisposableScopedContextWrapper : IDisposable
{
private readonly IServiceScope _scope;
public DbContext Context { get; }
public DisposableScopedContextWrapper(IServiceScope scope)
{
_scope = scope;
Context = _scope.ServiceProvider.GetService<DbContext>();
}
public void Dispose()
{
_scope.Dispose();
}
}
services.AddSingleton<Func<DisposableScopedContextWrapper>>(provider =>() =>
{
var scope = provider.CreateScope();
return new DisposableScopedContextWrapper(scope);
});
Ввести в свои классы Func<DisposableScopedContextWrapper> func
и использовать
using (var wrapper = func())
{
wrapper.Context...
}