首页 > 解决方案 > EF Core:如何插入数据相关表

问题描述

我是 Entity Framework Core 和学习的新手。

我有一个问题:我有三个具有多对多关系的表(产品、产品类别、类别)。一切正常,我可以更新、删除和添加数据库。

但我无法将Product数据添加到相关表中。它只是插入到Product表中,但我想将 Id 数据添加到ProductCategories.

谢谢你在这里帮助我。

这是我的代码:

通用存储库

public class EfCoreGenericRepository<TEntity, TContext> : IRepository<TEntity>
        where TEntity : class
        where TContext : DbContext, new()
{
    public virtual void Create(TEntity entity)
    {
        using (var context = new TContext())
        {
            context.Set<TEntity>().Add(entity);
            context.SaveChanges();
        }
    }

    public void Delete(TEntity entity)
    {
        using (var context = new TContext())
        {
            context.Set<TEntity>().Remove(entity);
            context.SaveChanges();
        }
    }

    public List<TEntity> GetAll()
    {
        using (var context = new TContext())
        {
            return context.Set<TEntity>().ToList();
        }
    }

    public TEntity GetById(int id)
    {
        using (var context = new TContext())
        {
            return context.Set<TEntity>().Find(id);
        }
    }

    public virtual void Update(TEntity entity)
    {
        using (var context = new TContext())
        {
            context.Entry(entity).State = EntityState.Modified;
            context.SaveChanges();
        }
    }
}

产品资料库

public class EfCoreProductRepository : EfCoreGenericRepository<Product, FoodContext>, IProductRepository
{
    public Product GetByIdWithCategories(int id)
    {
        using (var context = new FoodContext())
        {
            return context.Products
                          .Where(p => p.ProductId == id)
                          .Include(p => p.ProductCategories)
                          .ThenInclude(pc => pc.Category)
                          .FirstOrDefault();
        }
    }

    public List<Product> GetProductsByCategory(string name)
    {
        using (var context = new FoodContext())
        {
            var products = context.Products.AsQueryable();

            if (!string.IsNullOrEmpty(name))
            {
                products = products.Include(i => i.ProductCategories)
                                   .ThenInclude(i => i.Category)
                                   .Where(i => i.ProductCategories.Any(a => a.Category.Name.ToLower() == name.ToLower()));
            }

            return products.ToList();
        }
    }
        
    public void Update(Product entity, int[] categoryIds)
    {
        using (var context = new FoodContext())
        {
            var product = context.Products
                                 .Include(i => i.ProductCategories)
                                 .FirstOrDefault(i => i.ProductId == entity.ProductId);

            if (product != null)
            {
                product.Name = entity.Name;
                product.Price = entity.Price;
                product.ImageUrl = entity.ImageUrl;

                product.ProductCategories = categoryIds.Select(catid => new ProductCategory() {
                        ProductId = entity.ProductId,
                        CategoryId = catid
                    }).ToList();
            }

            context.SaveChanges();
        }
    }
    
    // I may override Create code here.
}

MVC Post 方法

[HttpPost]
public async Task<IActionResult> CreateProduct(ProductModel model, IFormFile file)
{
    if (ModelState.IsValid)
    {
        if (file != null)
        {
            var extension = Path.GetExtension(file.FileName);
            var randomName = string.Format($"{DateTime.Now.Ticks}{extension}");

            model.ImageUrl = randomName;

            var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot\\img\\Products", randomName);

            using (var stream = new FileStream(path, FileMode.Create))
            {
                await file.CopyToAsync(stream);
            }
        }

        var entity = new Product()
                {
                    Name = model.Name,
                    Price = model.Price,
                    ImageUrl = model.ImageUrl,
                    CategoryId = model.CategoryId
                };

        if (_productService.Create(entity))
        {
            TempData.Put("message", new AlertMessage
                    {
                        Title = $"{entity.Name} named product added successfully",
                        Message = $"{entity.Name} named product added successfully",
                        AlertType = "alert-success"
                    });
            return RedirectToAction("ProductList");
        };

        TempData.Put("message", new AlertMessage
                {
                    Title = _productService.ErrorMessage,
                    Message = _productService.ErrorMessage,

                });
    }

    ViewBag.Categories = _categoryService.GetAll();
    return View(model);
}

如果您需要查看它,您可以要求更多代码。现在谢谢!

编辑--->实体类

类别.cs

public class Category
    {
        public int CategoryId { get; set; }
        public string Name { get; set; }

        public string ImageUrl { get; set; }

        public List<ProductCategory> ProductCategories{get; set;}
    }

产品.cs

public class Product
    {
        public int ProductId { get; set; }
        public string Name { get; set; }
        public double? Price { get; set; }
        public bool IsApproved { get; set; }
        public int? CategoryId { get; set; }
        public string ImageUrl { get; set; }
        
        public List<ProductCategory> ProductCategories{get; set;}
    }

ProductCategories.cs

public class ProductCategory
    {
        public int CategoryId { get; set; }
        public Category Category { get; set; }
        public int ProductId { get; set; }
        public Product Product{get; set;}
    }

标签: asp.net-mvcentity-framework-core

解决方案


感谢海盗。我解决了问题。我是 efcore 的新手,但我知道多对多的关系是不必要的。我已经为许多类别的许多产品做过,但后来我改变了主意。也许我可以将它用于下一个代码。

public override void Create(Product entity)
        {
            base.Create(entity);
            using (var context = new FoodContext())
            {
                var product = context.Products
                                        .Where(i=>i.ProductId==entity.ProductId)
             

                       .Include(i=>i.ProductCategories).FirstOrDefault();
            
                product.ProductCategories.Add(new ProductCategory(){
                    ProductId=entity.ProductId,
                    CategoryId=(int)entity.CategoryId
                });
            
            context.SaveChanges();
        }
    }

注意:我不知道使用双重 using-code-block 有多真实


推荐阅读