如何在 Entity Framework ASP.NET 核心中进行添加和更新?

How to do both Add and Update in Entity Framework ASP.NET Core?

我想在 ASP.NET Core by Entity Framework Core 中使用相同的操作方法进行更新和添加,但是在添加到数据库中的记录列表后,我无法更新同样的记录到了table。它总是创建一组新的记录。

我的错误是什么?有人可以帮我吗?

    
  [HttpPost]        
        public IActionResult InsertProductDetails()
        {
            using WebClient wc = new WebClient();
            string contentString = wc.DownloadString(baseurl);
            List<Dictionary<string, string>> ListJsonProductContent = new List<Dictionary<string, string>>();          
            var token = JToken.Parse(contentString);
            if (token.Type == JTokenType.Array)  // "["
            {
                ListJsonProductContent = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(contentString);
            }
            else if (token.Type == JTokenType.Object) // "{"
            {
                var ObjectResponse = JsonConvert.DeserializeObject<Dictionary<string, object>>(contentString);
                foreach (var x in ObjectResponse)
                {
                    string key = x.Key.ToString();
                    string val = x.Value.ToString();
                    foreach (var dicItemML in JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(val))
                    {
                        ListJsonProductContent.Add(dicItemML);
                    }
                }
            }

            List<K360MappingMaster> ListMappedDataDb = new List<K360MappingMaster>();             
            var VLinqQuery = from KMM in _context.K360MappingMasters
                             where KMM.ApiUrl != null && KMM.ApiUrl == baseurl                            
                             select KMM;
            ListMappedDataDb = VLinqQuery.ToList();

            foreach (var dicItemML in ListJsonProductContent)
            {
                Dictionary<string, string> updItem = new Dictionary<string, string>();
                foreach (var itemMl in dicItemML)
                {
                    if (ListMappedDataDb.Select(s => s.ApiCatalog).ToList().Contains(itemMl.Key))
                    {
                        if (updItem.ContainsKey(ListMappedDataDb.Where(s => s.ApiCatalog == itemMl.Key).Select(s => s.K360Catalog).FirstOrDefault()))
                        {
                            if (ListMappedDataDb.Where(s => s.ApiCatalog == itemMl.Key).Select(s => s.K360Catalog).FirstOrDefault() == "Specification")
                            {
                                updItem[ListMappedDataDb.Where(s => s.ApiCatalog == itemMl.Key).Select(s => s.K360Catalog).FirstOrDefault()] += "<p>" + itemMl.Key + " :" + itemMl.Value + "<p>";
                            }
                            else
                            {
                                updItem[ListMappedDataDb.Where(s => s.ApiCatalog == itemMl.Key).Select(s => s.K360Catalog).FirstOrDefault()] += " " + itemMl.Value;
                            }
                        }
                        else
                        {
                            if (ListMappedDataDb.Where(s => s.ApiCatalog == itemMl.Key).Select(s => s.K360Catalog).FirstOrDefault() == "Specification")
                            {
                                updItem.Add(ListMappedDataDb.Where(s => s.ApiCatalog == itemMl.Key).Select(s => s.K360Catalog).FirstOrDefault(), "<p>" + itemMl.Key + " :" + itemMl.Value + "<p>");
                            }
                            else
                            {
                                updItem.Add(ListMappedDataDb.Where(s => s.ApiCatalog == itemMl.Key).Select(s => s.K360Catalog).FirstOrDefault(), itemMl.Value);
                            }
                        }
                    }
                    dicItemML.Remove(itemMl.Key);
                }
                foreach (var itemM2 in updItem)
                {
                    dicItemML.Add(itemM2.Key, itemM2.Value);
                }
            }
          
             List<CatalogProduct> ListKp = new List<CatalogProduct>();

            foreach (var dicItem in ListJsonProductContent)
                    {
                        try
                        {                            
                            CatalogProduct Ctgkp = new CatalogProduct
                            {    
                                Name = dicItem.ContainsKey("Name") ? dicItem["Name"] : "No Product",
                                Slug = dicItem.ContainsKey("Name") ? string.Concat(dicItem["Name"].Where(c => !char.IsWhiteSpace(c))).ToLower() : "No Slug",
                                Price = dicItem.ContainsKey("Price") ? decimal.Parse(dicItem["Price"], CultureInfo.InvariantCulture) : default,
                                ShortDescription = dicItem.ContainsKey("ShortDescription") ? dicItem["ShortDescription"] : null,
                                Description = dicItem.ContainsKey("Description") ? dicItem["Description"] : null,
                                Specification = dicItem.ContainsKey("Specification") ? dicItem["Specification"] : null,
                                RatingAverage = dicItem.ContainsKey("RatingAverage") ? double.Parse(dicItem["RatingAverage"], CultureInfo.InvariantCulture) : null,

                                MetaTitle = dicItem.ContainsKey("MetaTitle") ? dicItem["MetaTitle"] : null,
                                MetaKeywords = dicItem.ContainsKey("MetaKeywords") ? dicItem["MetaKeywords"] : null,
                                MetaDescription = dicItem.ContainsKey("MetaDescription") ? dicItem["MetaDescription"] : null,
                                Sku = dicItem.ContainsKey("Sku") ? dicItem["Sku"] : null,
                                Gtin = dicItem.ContainsKey("Gtin") ? dicItem["Gtin"] : null,
                                NormalizedName = dicItem.ContainsKey("NormalizedName") ? dicItem["NormalizedName"] : null,

                                StockQuantity = dicItem.ContainsKey("StockQuantity") ? int.Parse(dicItem["StockQuantity"], CultureInfo.InvariantCulture) : 50,
                                ReviewsCount = dicItem.ContainsKey("ReviewsCount") ? int.Parse(dicItem["ReviewsCount"], CultureInfo.InvariantCulture) : default,
                                DisplayOrder = dicItem.ContainsKey("DisplayOrder") ? int.Parse(dicItem["DisplayOrder"], CultureInfo.InvariantCulture) : 1,
                                OldPrice = dicItem.ContainsKey("OldPrice") ? decimal.Parse(dicItem["OldPrice"], CultureInfo.InvariantCulture) : null,
                                SpecialPrice = dicItem.ContainsKey("SpecialPrice") ? decimal.Parse(dicItem["SpecialPrice"], CultureInfo.InvariantCulture) : null,
                                SpecialPriceStart = dicItem.ContainsKey("SpecialPriceStart") ? DateTimeOffset.Parse(dicItem["SpecialPriceStart"], CultureInfo.InvariantCulture) : null,
                                SpecialPriceEnd = dicItem.ContainsKey("SpecialPriceEnd") ? DateTimeOffset.Parse(dicItem["SpecialPriceEnd"], CultureInfo.InvariantCulture) : null,

                                IsPublished = true,
                                PublishedOn = DateTimeOffset.Now,
                                CreatedById = 10,
                                IsDeleted = false,
                                CreatedOn = DateTimeOffset.UtcNow,
                                LatestUpdatedOn = DateTimeOffset.UtcNow,
                                LatestUpdatedById = 10,
                                HasOptions = false,
                                IsVisibleIndividually = true,
                                IsFeatured = true,
                                IsCallForPricing = false,
                                IsAllowToOrder = true,
                                StockTrackingIsEnabled = true
                        };
                            ListKp.Add(Ctgkp);
                           
                }

                        catch (Exception ex)
                        {
                            TempData["Exceptionmsg"] = ex;
                            return RedirectToAction("Index");
                            throw;
                        }
                    }

            int numP = 0;
            try
            {
                using (var transaction = _context.Database.BeginTransaction())
                {
                    int getcount = (from gcM in _context.CatalogProducts
                                    select gcM).Count();

                    if (getcount == 0)
                    {
                        _context.CatalogProducts.AddRange(ListKp);
                        _context.SaveChanges();

                    }
                    else
                    {
                        var catalogProducts = (from gcM in _context.CatalogProducts select gcM).ToList();
                        for (int i = 0; i < catalogProducts.Count; i++)
                        {
                            catalogProducts[i].Name = ListKp[i].Name;
                            catalogProducts[i].Price = ListKp[i].Price;
                            catalogProducts[i].Description = ListKp[i].Description;
                            catalogProducts[i].Specification = ListKp[i].Specification;
                            //...
                        }

                        _context.CatalogProducts.UpdateRange(catalogProducts);
                        _context.SaveChanges();

                    }


                    transaction.Commit();
                }
                if (numP > 0)
                {
                    TempData["Sucessmsg"] = "No conflicts. " + numP + " product details saved.";

                    (from p in _context.K360MappingMasters
                     where p.ApiUrl == baseurl
                     select p).ToList()
                                .ForEach(x => x.InsertStatusFlag = true);
                    _context.SaveChanges();

                    return RedirectToAction("Index");
                }

            }
            catch (Exception ex)
            {
                TempData["Exceptionmsg"] = ex;
                return RedirectToAction("Index"); ;
                throw;
            }
           

            return RedirectToAction("Index");
        }

我接受了你的回答。谢谢。但我对同一个问题没有更多的说明

1.CatalogProduct table 只有自动递增主键 ID 字段。我正在插入来自 JSON URL 的数据。唯一字段应该是产品名称。如何判断adding/updating条记录前的table条中是否已经存在商品名称

2.If我需要添加另一个JSONURL数据,如何区分这两个URL产品详情?

更新时没有跟踪到数据库中的实体,所以会直接添加它们。

您可以试试下面的代码。

else
{
    var catalogProducts= (from gcM in _context.CatalogProducts select gcM).ToList();
    for (int i = 0; i < catalogProducts.Count; i++)
    {
        catalogProducts[i].Name = ListKp[i].Name;
        catalogProducts[i].Price = ListKp[i].Price;
        //...
    }
                
    _context.CatalogProducts.UpdateRange(catalogProducts);
    numP = _context.SaveChanges();
                
}

更新:

using (var transaction = _context.Database.BeginTransaction())
{
    var catalogProducts = _context.CatalogProducts.ToList();
    foreach(var kp in ListKp)
    {
        if(!catalogProducts.Any(x => x.Name == kp.Name)){
            _context.CatalogProducts.Add(kp);
            _context.SaveChanges();
        }
        else
        {
            //Use AutoMapper automatically do the mapping
            var config = new MapperConfiguration(cfg => cfg.CreateMap<CatalogProduct, CatalogProduct>().ForMember(c => c.Id, opt => opt.Ignore()));
            var oldone = catalogProducts.FirstOrDefault(c => c.Name == kp.Name);
            var mapper = config.CreateMapper();
            oldone = mapper.Map<CatalogProduct,CatalogProduct>(kp, oldone);
            _context.CatalogProducts.Update(oldone);
            _context.SaveChanges();
        }
    }
    transaction.Commit();
}