Сохранение связанных данных (от многих ко многим) в EF Core 5 без получения фактических записей
Я создаю веб-приложение для бронирования обедов.
public class Food : BaseEntity
{
public int FoodId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Ingredients { get; set; }
public string PhotoPath { get; set; }
public ICollection<Menu> Menus { get; set; }
/*public ICollection<LunchReservation> LunchReservations { get; set; } omit */
}
public class Menu : BaseEntity
{
public Menu()
{
DateCreated = DateTimeOffset.Now;
DateModified = DateTimeOffset.Now;
}
public int MenuId { get; set; }
[Column(TypeName = "date")]
public DateTime MenuDate { get; set; }
public bool IsPublished { get; set; }
public ICollection<Food> Foods { get; set; }
/*public ICollection<LunchReservation> LunchReservations { get; set; } omit */
}
Все в порядке, но когда я хочу создать меню, в котором может быть 1 или более блюд, я получаю ошибку.
это мой Dto для создания меню
public class MenuCreationDto
{
public int[] FoodIds { get; set; }
public string MenuDate { get; set; }
}
и этот код не работает на сохранение.
var foods = menuCDto.FoodIds.Select(f => new Food() { FoodId = f }).ToList();
Menu newMenu = new()
{
MenuDate = menuDateInGregorian,
Foods = foods
};
await _db.Menus.AddAsync(newMenu);
await _db.SaveChangesAsync();
но для сохранения продуктов этот код работает, но я не хочу получать продукты из базы данных, чтобы просто составить меню.
var foods = _db.Foods.Where(f => menuCDto.FoodIds.Contains(f.FoodId)).ToList();
Menu newMenu = new()
{
MenuDate = menuDateInGregorian,
Foods = foods
};
await _db.Menus.AddAsync(newMenu);
await _db.SaveChangesAsync();
что я могу сделать для сохранения меню в базе данных без получения реальных продуктов из базы данных?
1 ответ
Вы можете использовать поддельные (также известные как заглушки) объекты, как в вашем нерабочем примере
var foods = menuCDto.FoodIds.Select(f => new Food() { FoodId = f }).ToList();
Но прежде чем позволить EF Core добавить родительский объект (Menu
), вы должны сообщить ему, что это "существующие" объекты, в противном случае он будет рассматривать их как "новые" и попытается вставить новые
Food
записи, а не ссылки, как предполагалось. Вы делаете это, прикрепляя их к контексту, который помечает их как существующие и неизменные:
_db.AttachRange(foods);
Остальной код будет таким же, но теперь должен работать.