У меня есть два объекта (Product и Supply), которые имеют отношения «многие ко многим». У меня также есть объект между ними, который содержит два идентификатора (SupplyProduct).
Мои сущности:
public class Product
{
[Key]
public int ProductId { get; set; }
[Required]
public string? ProductName { get; set; }
[Required]
[Column(TypeName = "decimal(6,2)")]
public decimal UnitPrice { get; set; }
public int Quantity { get; set; }
public string? Brand { get; set; }
public DateTime CreatedDateTime { get; set; } = DateTime.Now;
//Many to many relationship between the products and the stocks
public virtual ICollection<SupplyProduct>? SupplyProducts { get; set; }
}
public class Supply
{
[Key]
[Required]
public int SupplyId { get; set; }
[Required]
[DisplayName("Supply's Label")]
public string? Label { get; set; }
//One to many relationship between the Stock and the Merchant
public Merchant? Merchant { get; set; }
//Many to many relationship between the stocks and the products
public virtual ICollection<SupplyProduct>? SupplyProducts { get; set; }
}
public class SupplyProduct
{
[Key]
public int SupplyId { get; set; }
public virtual Supply? Supply { get; set; }
[Key]
public int ProductId { get; set; }
public virtual Product? Product { get; set; }
}
Я хочу назначить поставку продукту при его создании. а затем показать поставку с сопутствующими продуктами
это мой контроллер продуктов:
ПродуктыController.cs
public class ProductController : Controller
{
private readonly ApplicationDbContext _db;
public ProductController(ApplicationDbContext db)
{
_db = db;
}
// GET: ProductController
public ActionResult Index()
{
IEnumerable<Product> ProductsList = _db.Products;
return View(ProductsList);
}
// GET: ProductController/Create
public ActionResult Create()
{
IEnumerable<Supply> SuppliesList = _db.Supplies.Include(s => s.Merchant);
ViewBag.Supplies = SuppliesList;
return View();
}
// POST: ProductController/Create
[HttpPost]
public ActionResult Create(Product model, List<int> supplyIds)
{
_db.Products.Add(model);
_db.SaveChanges();
SupplyProduct SP = new();
foreach (var supplyId in supplyIds)
{
SP.SupplyId = supplyId;
SP.ProductId = model.ProductId;
SP.Product = model;
SP.Supply = _db.Supplies.Where(x => x.SupplyId == supplyId).FirstOrDefault();
}
_db.SupplyProducts.Add(SP);
_db.SaveChanges();
return RedirectToAction(nameof(Index));
}
}
Не могли бы вы проверить метод моего поста Create
, если он такой, каким он должен быть, и как я могу получить данные о продуктах при возврате расходных материалов в методе Index
в представление индекса?
Большое спасибо за вашу помощь и счастливого кодирования: D
Вы можете удалить вкладку SupplyProduct, если нет дополнительных свойств ни в чем, кроме Supply Product, который вам не нужен для многих-ко-многим. Затем инициализируйте коллекции в снабжении и продукте.
public class Product
{
public Product()
{
this.Supplys = new HashSet<Supply>();
}
//... your props
public virtual ICollection<Supply> Supplys { get; set; }
}
public class Supply
{
public Supply()
{
this.Products = new HashSet<Product>();
}
//... your props
public virtual ICollection<Product> Products { get; set; }
}
Добавьте продукт в поставку только с одним запросом (в вашем коде вы делаете запрос для каждого идентификатора в supplyIds
)
[HttpPost]
public ActionResult Create(Product model, List<int> supplyIds)
{
//Get all supplys you need by id
var supplys = _db.Supplys
.Where(x => supplyIds.Contains(x.SupplyId))
.ToList();
//Add product in each supply
foreach (var supply in supplys)
{
supply.Products.Add(model);
}
//Update db
_db.SaveChanges();
return RedirectToAction(nameof(Index));
}
Получить из БД
public ActionResult GetSuplys(List<int> supplyIds)
{
//Here you get all Supplys with the Products in it
var supplys = _db.Supplys
.Include(x => x.Products)
.Where(x => supplyIds.Contains(x.SupplyId))
.ToList();
//...
}
Сохранить новую поставку продукта
public ActionResult NewSuply()
{
var supply = new Supply
{
ProductName = name,
//Add all props you need
//You can add Product here or add empty collection
Products.Add(product), or = new List<Product>();
}
//No need to save Product separate
_db.Add(supply);
_db.SaveChanges();
}
Не могли бы вы проверить мой метод создания сообщения, если он такой, каким должен быть?
Измените свой код, как показано ниже, иначе вы всегда будете хранить второй запас в supplyIds
:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Product model, List<int> supplyIds)
{
_context.Product.Add(model);
_context.SaveChanges();
SupplyProduct SP = new();
foreach (var supplyId in supplyIds)
{
SP.SupplyId = supplyId;
SP.ProductId = model.ProductId;
SP.Product = model;
SP.Supply = _context.Supply.Where(x => x.SupplyId == supplyId).FirstOrDefault();
_context.SupplyProducts.Add(SP); //move to here...
_context.SaveChanges();
}
// _context.SupplyProducts.Add(SP);
//_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
как я могу получить данные о продуктах при возврате расходных материалов в методе индекса в представление индекса?
Измените метод индекса, как показано ниже:
// GET: Products
public async Task<IActionResult> Index()
{
var data = await _context.Product.Include(p => p.SupplyProducts)
.ThenInclude(sp => sp.Supply).ToListAsync();
return View(data);
}