【问题标题】:EF Core : how to Insert data releated tablesEF Core:如何插入数据相关表
【发布时间】:2021-03-29 05:02:00
【问题描述】:

我是 Entity Framework Core 和学习新手。

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

但我无法将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 发布方法

[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);
}

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

编辑 ---> 实体类

Category.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;}
    }

【问题讨论】:

  • 您可以将您的实体类添加到问题中吗?你确定 model.CategoryId 不为空吗?
  • 感谢您的回答。我也添加了实体类。 CategoryId 为空,因为我想通过错误消息手动控制它。
  • 感谢您的更新。为什么你有公共 int?产品类中的 CategoryId? ProductCategory 应该管理您在 Product 和 Category 之间的关系。
  • 你说了很多对很多。真的吗?一个产品真的可以属于多个类别吗?我可以理解具有许多产品的类别,但不一定反过来。
  • @memo1093 我没有看到试图在ProductCategory 中插入记录的代码。分配Product.CategoryId = model.CategoryId 不会神奇地在ProductCategory 中添加记录。添加产品_productService.Create(entity) 后,您应该可以从entity 变量中获取新插入记录的id,然后对ProductCategory 记录执行另一个数据库操作。附带说明一下,产品中不需要CategoryId,因为存在多对多关系。

标签: asp.net-mvc entity-framework-core


【解决方案1】:

感谢海盗。我解决了问题。我是 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 的真实性如何

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-03
    • 1970-01-01
    • 1970-01-01
    • 2019-11-17
    • 1970-01-01
    • 2020-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多