EF core пытается обновить таблицу, которую я не указал - PullRequest
0 голосов
/ 24 июня 2018

У меня есть класс 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 голосов
/ 25 июня 2018

Кажется, что Entity Framework не видит 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.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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...