0
votes

I'm dropping database, creating it again and Seeding with data.

With this type of registry everything works fine

services.AddDbContext<Context>
(
   options => options.UseSqlServer(Configuration["Database"]
);

But, when I add ServiceLifetime.Transient then instantly it throws various exceptions like:

services.AddDbContext<Context>
(
   options => options.UseSqlServer(Configuration["Database"], ServiceLifetime.Transient
);

SqlException: Violation of PRIMARY KEY constraint 'PK_myTable'. Cannot insert duplicate key in object 'dbo.myTable'. The duplicate key value is ( [guid] ). The statement has been terminated.

SqlException: Cannot insert explicit value for identity column in table 'myTable' when IDENTITY_INSERT is set to OFF.

What may be wrong?

public void Configure(IApplicationBuilder app, IHostingEnvironment env, Context context, SignInManager<User> sm, UserManager<User> um)
{
    (...)
    context.Database.EnsureDeleted();
    context.Database.EnsureCreated();
    new Initializer(context, um).Initialize().Wait();
    (...)
}

public class Initializer
{
    private readonly UserManager<User> _userManager;
    private readonly Context _ctx;

    public Initializer(Context c, UserManager<User> um)
    {
        _ctx = c;
        _userManager = um;
    }

    public async Task Initialize()
    {
        filling my objects with data

        (No, I'm not setting value to Id anywhere)
        _ctx.SaveChanges();
    }

I bet that's because of async / .Wait()?

1
Can you show the code that drops/creates and feeds the data? - juunas
@juunas Added the code - Joelty
Aha, it might be because UserManager is getting a different context instance. Remember that Transient means each object that requires it will get their own instance each time. - juunas
Yes, every single time an instance is asked from the DI container, a new instance is created (if it is Transient). - juunas
That previous issue is almost certainly down to using async without awaiting, which is a problem that you actually need to solve, not just side-step by making the lifetime transient. Regardless, your context should not be transient for a whole host of reasons, this issue now being one. Leave it in request scope and fix your real problem. - Chris Pratt

1 Answers

0
votes

Solution:

I removed

ServiceLifetime.Transient

and then in my Initializer class I added .Wait() to

userManager.CreateAsync();

Because I've been creating users dynamically.

and it stopped throwing exceptions about context being used in other thread.

or generally await it?