dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.72k stars 3.17k forks source link

Exception when MARS not enabled #3244

Closed staff0rd closed 8 years ago

staff0rd commented 9 years ago

I'm assuming MARS is no longer a requirement due to PR #2198 and #1665, but the following snippet results in UserManager.AddToRoleAsync throwing System.InvalidOperationException: Operation is not valid due to the current state of the object. when MultipleActiveResultSets=false.

CODE

public class Program
{
    public void Main(string[] args)
    {
        var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
        SetRole(userManager).Wait();
    }

    private async static Task SetRole(UserManager<ApplicationUser> userManager)
    {
        try
        {
            var user = await userManager.FindByNameAsync("myUser"); // successful
            await userManager.AddToRoleAsync(user, "myRole"); // exception
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }

    private readonly IServiceProvider serviceProvider;

    public IConfigurationRoot Configuration { get; private set; }

    public Program(IApplicationEnvironment env, IServiceManifest serviceManifest)
    {
        Configuration =
            new ConfigurationBuilder(Directory.GetCurrentDirectory())
            .AddJsonFile("config.json")
            .AddEnvironmentVariables()
            .Build();

        var services = new ServiceCollection();
        ConfigureServices(services);
        serviceProvider = services.BuildServiceProvider();
    }

    private void ConfigureServices(IServiceCollection services)
    {
        var connectionString = Configuration["Data:DefaultConnection:ConnectionString"];

        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(connectionString));

        services.AddIdentity<ApplicationUser, IdentityRole>()
           .AddEntityFrameworkStores<ApplicationDbContext>()
           .AddDefaultTokenProviders();

        services.AddLogging();
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    }
}

OUTPUT

System.AggregateException: One or more errors occurred. ---> System.AggregateException: One or more errors occurred. ---> System.InvalidOperationException: Operation is not valid due to the current state of the object.
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Data.Entity.Query.TaskResultAsyncEnumerable`1.Enumerator.<MoveNext>d__3.MoveNext()
   --- End of inner exception stack trace ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Data.Entity.Query.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.<MoveNext>d__5.MoveNext()
   --- End of inner exception stack trace ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Identity.EntityFramework.UserStore`4.<AddToRoleAsync>d__32.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Identity.UserManager`1.<AddToRoleAsync>d__92.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Fanatics.ConsoleApp.Program.<SetRole>d__1.MoveNext() in c:\git\Fanatics\Fanatics.ConsoleApp\Program.cs:line 32
---> (Inner Exception #0) System.AggregateException: One or more errors occurred. ---> System.InvalidOperationException: Operation is not valid due to the current state of the object.
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Data.Entity.Query.TaskResultAsyncEnumerable`1.Enumerator.<MoveNext>d__3.MoveNext()
   --- End of inner exception stack trace ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Data.Entity.Query.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.<MoveNext>d__5.MoveNext()
---> (Inner Exception #0) System.InvalidOperationException: Operation is not valid due to the current state of the object.
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Data.Entity.Query.TaskResultAsyncEnumerable`1.Enumerator.<MoveNext>d__3.MoveNext()<---
<---
rowanmiller commented 8 years ago

I am not able to reproduce this issue. Here is the code I used against 7.0.0-rc1-final. If you are still able to reproduce the issue, then feel free to re-open.

using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Internal;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Data.Entity;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var services = new ServiceCollection();

            services.AddEntityFramework()
                .AddSqlServer()
                .AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=Identity;Trusted_Connection=True;"));

            services.AddIdentity<ApplicationUser, IdentityRole>()
               .AddEntityFrameworkStores<ApplicationDbContext>()
               .AddDefaultTokenProviders();

            services.AddLogging();
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            var serviceProvider = services.BuildServiceProvider();

            var context = serviceProvider.GetRequiredService<ApplicationDbContext>();
            var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
            var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();

            Setup(context, userManager, roleManager).Wait();
            SetRole(userManager).Wait();
        }

        private async static Task Setup(ApplicationDbContext context, UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager)
        {
            context.Database.EnsureCreated();

            if (!userManager.Users.Any())
            {
                await userManager.CreateAsync(new ApplicationUser { UserName = "myUser", Email = "myUser@sample.com" });
            }

            if (!roleManager.Roles.Any())
            {
                await roleManager.CreateAsync(new IdentityRole("myRole"));
            }
        }

        private async static Task SetRole(UserManager<ApplicationUser> userManager)
        {
            try
            {
                var user = await userManager.FindByNameAsync("myUser"); // successful
                await userManager.AddToRoleAsync(user, "myRole"); // exception
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
    }

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
    }

    public class ApplicationUser : IdentityUser
    {
    }
}