Вопрос или проблема
Я работаю над проектом интернет-магазина. В проекте есть модель под названием Product, которая имеет отношение многих ко многим с моделью под названием Color через модель Product-Color. Я хочу добавить свойство под названием Quantity в Product-Color для каждого Color, который я добавляю. Я использую Razor Page и .net 8
.
Вот что я уже сделал.
Это представление:
<div class="form-group">
<label>Цвета</label>
@{
var colors = ViewData["Colors"] as List<Color>;
}
@foreach (Color color in colors)
{
<div>
<input type="checkbox" name="SelectedColors" value="@color.ColorId"/>@color.ColorName
<div>
<label>Количество</label>
<input type="number" name="ColorQuantities" class="form-control" />
</div>
<hr/>
</div>
}
</div>
Это код за страницей:
public IActionResult OnPost(IFormFile imgProductUp, List<int> SelectedColors, List<int>? ColorQuantities)
{
if (!ModelState.IsValid)
{
return Page();
}
int productId = _productService.AddProduct(Product, imgProductUp);
_productService.AddColorToProductByAdmin(productId, SelectedColors, ColorQuantities);
return RedirectToPage("Index");
}
Это сервис:
public void AddColorToProductByAdmin(int productId, List<int>? SelectedColor, List<int>? ColorQuantities)
{
foreach (int color in SelectedColor)
{
foreach (int quantity in ColorQuantities)
{
_context.ProductColors.Add(new ProductColor()
{
ProductId = productId,
ColorId = color,
Quantity = quantity
});
}
}
_context.SaveChanges();
}
Я хочу назначить свойство “Quantity” для выбранного ColorId в таблице Product-Color, но мои коды создают два цикла.
Вот что я получаю в своей базе данных:
Существует цикл для списка colorId и цикл для списка quantity. Я просто хочу знать, как я могу отправить список количества и предотвратить повторение списка colorId дважды при добавлении списка количества.
Так что мне нужно руководство о том, как решить эту проблему.
Вы перебираете три цвета, затем для каждого цвета добавляете все три количества. Предполагая, что два списка согласованы друг с другом, использование одного for
цикла решит вашу задачу:
public void AddColorToProductByAdmin(int productId, List<int>? SelectedColor, List<int>? ColorQuantities)
{
if (SelectedColor is null)
return; // нет цветов
for (int i = 0; i < SelectedColor.Count; i++)
{
_context.ProductColors.Add(new ProductColor()
{
ProductId = productId,
ColorId = SelectedColor[i],
Quantity = ColorQuantities?[i]
});
}
_context.SaveChanges();
}
Ответ или решение
Ваша проблема заключается в том, что при сохранении связанного элемента в таблице с многими ко многим вы получаете дублирующиеся записи в базе данных. Основной причиной этого является то, что вы используете вложенные циклы для обработки выбранных цветов и количеств, что приводит к созданию множества записей для каждой комбинации цвета и количества.
В вашем текущем коде в методе AddColorToProductByAdmin
происходит следующее:
- Вы итератором проходите по всем выбранным цветам.
- Для каждого цвета вы снова запускаете итерацию по списку количеств, добавляя к каждому цвету все доступные количества. Это приводит к тому, что каждый цвет получает все суммы, что и создает дублирования.
Для решения вашей проблемы, необходимо просто использовать один цикл, в котором вы будете одновременно итеративно получать ColorId
и соответствующее ему Quantity
, предполагая, что списки SelectedColors
и ColorQuantities
имеют одинаковую длину и соответствие.
Вот переработанный код, который решает вашу задачу:
public void AddColorToProductByAdmin(int productId, List<int>? SelectedColor, List<int>? ColorQuantities)
{
// Проверка на случай, если список цветов пуст
if (SelectedColor is null || ColorQuantities is null || SelectedColor.Count != ColorQuantities.Count)
return; // Или обработка ошибки, если это необходимо
// Использование одного цикла для обработки обоих списков
for (int i = 0; i < SelectedColor.Count; i++)
{
_context.ProductColors.Add(new ProductColor()
{
ProductId = productId,
ColorId = SelectedColor[i],
Quantity = ColorQuantities[i] // Берем количество по индексу i
});
}
// Сохранение изменений в базе данных
_context.SaveChanges();
}
Объяснение изменений:
- Проверка аргументов: Мы добавили проверку длины списков, чтобы избежать потенциальных ошибок, если они будут разной длины.
- Упрощение цикла: С помощью одного цикла мы объединяем информацию о цветах и количествах, что предотвращает дублирование и позволяет точно сопоставить каждый цвет с соответствующим количеством.
Важные моменты:
- Убедитесь, что на уровне пользовательского интерфейса ваши списки точно соответствуют друг другу: каждая галочка на цвете должна иметь соответствующее количество.
- Дополнительно, при добавлении новых свойств в модель (в данном случае
Quantity
), важно внимательно следить за миграциями базы данных и их корректным выполнением.
Таким образом, приведенный код решает вашу проблему. Теперь при добавлении каждого цвета в таблицу ProductColor
будет добавляться соответствующее количество, избегая дублирования. Если у вас остались вопросы, не стесняйтесь спрашивать!