EF核心尝试更新我未指定的表

时间:2018-06-24 20:32:36

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

我有一个叫做BasketItem的类

public class BasketItem
{
    [Key]
    public int BasketItemId { get; set; }

    public Product Product {get;set;}

    public Basket Basket {get; set; }

}

其中有对另外两个类的引用。产品和购物篮。

public class Basket
{
    [Key]
    public int BasketId { get; set; }

    public IdentityUser IdentityUser { get; set; }
}

篮子包含一个ID和对IdentityUser的引用

但是,在运行代码时出现此异常。 Exception

我不明白为什么它要尝试使用重复的帐户更新IdentiyUser表,而我只想尝试更新BasketItem表。

初始调用代码

[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Add(int productId)
{
    string userId = userManager.GetUserId(User);
    IdentityUser identityUser = await accountManager.GetCurrentUserAsync(userId);
    Basket basket = await basketManager.GetUserBasketAsync(identityUser);

    await basketManager.AddProductToBasketAsync(productId, basket);

    return RedirectToAction(nameof(Index));
}

致电客户经理:

public async Task<IdentityUser> GetCurrentUserAsync(string accountId)
{
    if (!(String.IsNullOrEmpty(accountId) || String.IsNullOrWhiteSpace(accountId)))
        return await accountRepository.GetCurrentUserAsync(accountId);
    else throw new ArgumentNullException();
}

帐户回购

public async Task<IdentityUser> GetCurrentUserAsync(string accountId)
{
    var task = Task.Run(() => context.Users.Where(x => x.Id == accountId).FirstOrDefault());
    return await task;
}

购物篮经理致电

public async Task<Basket> GetUserBasketAsync(IdentityUser identityUser)
{
    if (identityUser != null)
        return await basketRepository.GetUserBasketAsync(identityUser);
    else throw new ArgumentException();
}

购物篮回购电话

public async Task<Basket> GetUserBasketAsync(IdentityUser identityUser)
{
    //Include method returns related Entity. 
    var task = Task.Run(() => context.Basket.Include(x => x.IdentityUser).Where(x => x.IdentityUser.Id == identityUser.Id).SingleOrDefault());
    return await task;
}

购物篮添加管理员呼叫

public async Task<int> AddProductToBasketAsync(int productId, Basket basket)
{
    if (basket == null)
        throw new ArgumentException();

    Product product = await productManager.GetProductByIdAsync(productId);

    if (product == null)
        throw new Exception("Could not retrieve product");

    return await basketRepository.AddProductToBasketAsync(product, basket);
}

产品经理电话

public async Task<Product> GetProductByIdAsync(int? id)
{
    return await productRepository.GetProductByIdAsync(id);
}

产品回购电话

public async Task<Product> GetProductByIdAsync(int? id)
{
    return await context.Products.SingleOrDefaultAsync(x => x.ProductId == id);
}

1 个答案:

答案 0 :(得分:0)

似乎实体框架没有将ApplicationUser视为已经存在的实体。我建议您在模型中保持明确,不要让它自己决定:

public class BasketItem
{
    [Key]
    public int BasketItemId { get; set; }

    // add the actual columns
    public int ProductId { get; set; }    
    public int BaskedId { get; set; }

    public Product Product {get;set;}
    public Basket Basket {get; set; }
}

public class Basket
{
    [Key]
    public int BasketId { get; set; }

    // I believe it's a string but it could be a System.Guid instead
    public string IdentityUserId { get; set; }

    public IdentityUser IdentityUser { get; set; }
}

由于GetUserBasketAsync中对Task Parallel Library的错误使用,也可能发生这种情况。我建议您删除对Task.Run的调用,而改用Entity Framework提供的正确异步的方法:

// async modifier not needed here
public Task<Basket> GetUserBasketAsync(IdentityUser identityUser)
{
    //Include method returns related Entity. 
    return context.Basket
        .Include(x => x.IdentityUser)
        .Where(x => x.IdentityUser.Id == identityUser.Id)
        // use the asynchronous version instead of the synchronous one
        .SingleOrDefaultAsync();
}

请注意,GetCurrentUserAsync上也会发生相同的问题,因此请相应地对其进行修改:

public Task<IdentityUser> GetCurrentUserAsync(string accountId)
{
    return context.Users
        .Where(x => x.Id == accountId)
        .SingleOrDefaultAsync();
}