[EF Core] [XUnit] {'Id'}已被跟踪

时间:2020-05-21 22:14:25

标签: c# asp.net-core entity-framework-core xunit

我知道有很多这样的问题,我已经阅读了几个小时,并且尝试了很多方法,但是找不到任何解决方案。

问题出在这里:

我有一个名为Language的实体,该实体继承了BaseEntiy(具有ID)。我正在尝试在我的服务上测试删除方法,但它会抛出错误消息,提示您您没有问题标题。

我的项目有一个包含GetById方法和Delete方法的存储库:

        public async Task<T> GetById(int id)
    {
        return await _dbContext.Set<T>()
            .AsNoTracking()
            .FirstOrDefaultAsync(e => e.Id == id);
    }

    public async Task Delete(int id)
    {
        var entity = await GetById(id);
        _dbContext.Set<T>().Remove(entity);
        await _dbContext.SaveChangesAsync();
    }

在我的服务中,我这样调用该存储库:

    public async Task DeleteLanguageAsync(ApplicationUser invoker, int id)
    {
        _validator.ValidateUser(invoker, _localizer);
        CheckIfIsAdmin(invoker.Id);

        await _languageRepository.Delete(id);
    }

我要测试它:

        [Fact]
    [Trait("Category", "Integration test")]
    public async Task DeleteLanguageAsyncShould()
    {
        var user = await _services.InitializeUserAndRole("AAA", "admin");
        var toDelte = await _services.UserContext.Languages.FirstOrDefaultAsync();
        await _services.LanguageService.DeleteLanguageAsync(user, toDelte.Id);
        var expect = await _services.UserContext.Languages.FirstOrDefaultAsync(x => x.Id == toDelte.Id);

        Assert.Null(expect);
    }

在_service中,我像这样初始化dbContext:

        services
            .AddDbContext<UsersContext>(o => o.UseInMemoryDatabase("dbName"))
            .AddIdentity<ApplicationUser, ApplicationRole>(options =>
        {
            options.SignIn.RequireConfirmedEmail = true;
            options.Password.RequireDigit = true;
            options.Password.RequireLowercase = true;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireUppercase = true;
            options.Password.RequiredLength = 8;
        })
            .AddEntityFrameworkStores<UsersContext>()
            .AddRoleManager<ApplicationRoleManager<ApplicationRole>>()
            .AddDefaultTokenProviders();

我要处理它:

public void Dispose()
{
    UserContext.Database.EnsureDeleted();
    UserContext.Dispose();
}

内存数据是由EntityBuilder静态类生成的。在这种情况下,我使用的是GetLanguages方法:

        public static List<Language> GetLanguages()
    {
        return new List<Language>()
        {
            new Language()
            {
                IsDefault = true,
                LongName = "Español",
                ShortName = "ESP",
                EncodedName = "es"
            },
            new Language()
            {
                IsDefault = true,
                LongName = "English",
                ShortName = "ENG",
                EncodedName = "en"
            },

        };
    }

这是完整的错误:

System.InvalidOperationException:实体类型的实例 无法跟踪“语言”,因为另一个具有相同语言的实例 {'Id'}的键值已被跟踪。附加现有时 实体,请确保只有一个具有给定键值的实体实例 被附上。考虑使用 'DbContextOptionsBuilder.EnableSensitiveDataLogging'以查看 冲突的键值。

0 个答案:

没有答案