首页 > 解决方案 > AspNetUserManager:添加和删除用户时出现跟踪错误

问题描述

使用 AspNetUserManager 时遇到问题。如果我添加用户并删除用户(不重新创建用户管理器),我会收到此错误:

System.InvalidOperationException :无法跟踪实体类型“ApplicationUser”的实例,因为已在跟踪另一个具有键值“{Id: XXX}”的实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。

我已经设置了“QueryTrackingBehavior.NoTracking”,但它没有任何效果。

我在没有依赖注入的 WebForms 应用程序中使用 Usermanager。所以,我正在“手动”创建对象:

public class ApplicationUserManager : AspNetUserManager<ApplicationUser>
    {
        private static UserStore<ApplicationUser, MyRole, ApplicationDbContext, Guid>  CreateUserStore(string connectionString)
        {
            var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>(); 
            optionsBuilder.UseSqlServer(connectionString);
            optionsBuilder.EnableSensitiveDataLogging(true);

            // IMPORTANT: https://github.com/dotnet-architecture/eShopOnContainers/issues/10
            // https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbcontextoptionsbuilder.usequerytrackingbehavior?view=efcore-3.1
            optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); 

            var userStore = new UserStore<ApplicationUser, MyRole, ApplicationDbContext, Guid>(
                new ApplicationDbContext(optionsBuilder.Options)
                );
            return userStore;
        }
        public ApplicationUserManager(string connectionString)
            :base(
                 CreateUserStore(connectionString),
                 null,
                 new SqlPasswordHasher(), // custom hasher for old Membership passwords
                 new List<UserValidator<ApplicationUser>>() { new UserValidator<ApplicationUser>() },
                 null,
                 null,
                 null,
                 null,
                 null)
        {

        }
    }

在普通的 MVC 应用程序中,我会尝试配置“services.AddScoped<..>”,如下所述:https ://entityframework.net/knowledge-base/48202403/instance-of-entity-type-cannot-be-tracked -因为另一个实例具有相同的键值被跟踪

但我不知道如何在 WebForms 应用程序中执行此操作。你有什么想法?

更新: 我想添加更多信息:在我们的代码(遗留代码)中,用于创建用户的 ApplicationUser 对象被复制然后返回。所以如果我想删除它,我正在删除复制的对象。是否有可能“摧毁”旧物体?还是将其从跟踪中删除?还是我每次都必须使用原始对象?我可以按 ID 删除用户吗?

var res = applicationUserManager.CreateAsync(user, "password").Result;
ApplicationUser userCopy = new ApplicationUser(user); // COPY
var res2 = applicationUserManager.DeleteAsync(userCopy).Result; // TRACKING EXCEPTION

我的解决方案 再次获取用户(FindByIdAsync)并删除/更新该用户对象!

标签: c#webformsasp.net-identity.net-standard

解决方案


推荐阅读