AspNetUserManager: ошибка отслеживания при добавлении и удалении пользователей - PullRequest
1 голос
/ 10 февраля 2020

У меня проблема при использовании AspNetUserManager. Если я добавляю пользователя и удаляю пользователя (без воссоздания Usermanager между ними), я получаю эту ошибку:

System.InvalidOperationException: экземпляр типа сущности ApplicationUser не может быть отслежен, поскольку другой экземпляр с значение ключа '{Id: XXX}' уже отслеживается. При присоединении существующих сущностей убедитесь, что присоединен только один экземпляр сущности с данным значением ключа.

Я уже установил «QueryTrackingBehavior.NoTracking», но это не оказало никакого влияния.

Я использую Usermanager в приложении WebForms без внедрения зависимостей. Итак, я создаю объект «вручную»:

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-because-another-instance-with-same-key-value-is-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

Мое решение Получить пользователя ОПЯТЬ (FindByIdAsyn c) и удалить / обновить этот объект пользователя!

...