首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何检查数据库中是否存在特定ID的记录,避免已发布的ASP.NET核心MVC应用出现“违反主键约束”错误?

如何检查数据库中是否存在特定ID的记录,避免已发布的ASP.NET核心MVC应用出现“违反主键约束”错误?
EN

Stack Overflow用户
提问于 2019-06-11 05:08:36
回答 1查看 1.7K关注 0票数 0

因此,我已经构建了一个小的ASP.NET核心在线商店应用程序有一段时间了,其中一个必要的部分是关闭某些表中的自动ID生成。当我想要在购物车中添加一些产品时,应用程序会生成一个SqlException: Violation of PRIMARY KEY constraint 'PK_Tip'. Cannot insert duplicate key in object 'dbo.Tip'. The duplicate key value is (1). The statement has been terminated.异常。

它的来源无疑是TipKreator类,它用一些用于测试的类型初始化数据库,有时会让应用程序认为生成了新的类型,所有这些类型都想使用专用的PKs。

我正在寻找一个解决方案来检查这些记录是否存在于我的EF Core数据库中,然后再将它们添加到我的列表中。完整的错误报告:

Korpa.cs中的BestDeal.Models.Korpa.DodajUKorpu(Artikal artikal,int kolicina)

        else
        {
            elementKorpe.KolicinaArtikla++;
        }
        try
        {
            **_context.SaveChanges();**
        }
        finally
        {
            _context.Database.CloseConnection();
        }
    }

BestDeal.Controllers.KorpaAppController.DodajKorpa(int artikalID)在KorpaAppController.cs中

       // WriteErrorLog(artikalID.ToString());
        Artikal odabrani = _artikliApp.artikliApp.FirstOrDefault(p => p.IdArtikla == artikalID);
        if (odabrani != null)
        {
            _korpica.DodajUKorpu(odabrani, 1);
        }
        **return RedirectToAction("Index");**
    }

TipKreator.cs

public class TipKreator:ITipovi
    {
        List<Tip> listaTipova = new List<Tip>{new Tip { Ime = "Laptopi", idTipa = 1 },
                    new Tip { Ime = "Mobiteli", idTipa = 2 },
                    new Tip { Ime = "Računari", idTipa = 3 },
                    new Tip { Ime = "Računarska oprema", idTipa = 4 } };
        public IEnumerable<Tip> tipoviApp
        {

            get {
                return listaTipova;
            }
        }
        public Tip vratiTip(string nazivTipa)
        {
            foreach (Tip t in listaTipova) if (t.Ime.Equals(nazivTipa)) return t;
            return null; //FLAG
        }
    }

Korpa.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;

namespace BestDeal.Models
{
    //Hajmo reci da je samo lista artikala i njihovih kolicina za pocetak
    //TODO: Integracija ocjena i svega
    public class Korpa
    {
        private readonly BestDealContext _context;

        //List<Tuple<Artikal, Recenzija, double>> podaciOArtiklima;
        [Required]
       List<KorpaInfo> artikliKolicina;
        string idKorpe;
        public Korpa()
        {
        }

        public Korpa(BestDealContext context)
        {
            _context = context;
        }

        public Korpa(string idKorpe, List<KorpaInfo> artikliKolicina)
        {
            IdKorpe = idKorpe;
            ArtikliKolicina = artikliKolicina;
        }

        public static Korpa DajKorpu(IServiceProvider services)
        {
            ISession session = services.GetRequiredService<IHttpContextAccessor>()?
                .HttpContext.Session;

            var context = services.GetService<BestDealContext>();
            string cartId = session.GetString("idKorpe") ?? Guid.NewGuid().ToString();

            session.SetString("idKorpe", cartId);

            return new Korpa(context) { idKorpe = cartId };
        }

        public void DodajUKorpu(Artikal artikal, int kolicina)
        {
            var elementKorpe =
                    _context.KorpaInfo.SingleOrDefault(
                        s => s.A.IdArtikla == artikal.IdArtikla && s.IdKorpe1 == idKorpe);

            if (elementKorpe == null)
            {
                elementKorpe = new KorpaInfo
                {
                    IdKorpe1 = idKorpe,
                    A = artikal,
                KolicinaArtikla = 1
            };

            _context.KorpaInfo.Add(elementKorpe);
            }
            else
            {
                elementKorpe.KolicinaArtikla++;
            }
            try
            {
                _context.SaveChanges();
            }
            finally
            {
                _context.Database.CloseConnection();
            }
        }

        public int IzbaciIzKorpe(Artikal artikal)
        {
            var elementKorpe =
                    _context.KorpaInfo.SingleOrDefault(
                        s => s.A.IdArtikla == artikal.IdArtikla && s.IdKorpe1 == IdKorpe);

            var localAmount = 0;

            if (elementKorpe != null)
            {
                if (elementKorpe.KolicinaArtikla > 1)
                {
                    elementKorpe.KolicinaArtikla--;
                    localAmount = elementKorpe.KolicinaArtikla;
                }
                else
                {
                    _context.KorpaInfo.Remove(elementKorpe);
                }
            }

            _context.SaveChanges();

            return localAmount;
        }

        public List<KorpaInfo> DajNaruceneArtikle()
        {
            return artikliKolicina ??
                   (ArtikliKolicina =
                       _context.KorpaInfo.Where(c => c.IdKorpe1 == idKorpe)
                           .Include(s => s.A)
                           .ToList());
        }

        public void ClearCart()
        {
            var cartItems = _context
                .KorpaInfo
                .Where(cart => cart.IdKorpe1 == idKorpe);

            _context.KorpaInfo.RemoveRange(cartItems);

            _context.SaveChanges();
        }

        public decimal DajUkupnuCijenu()
        {
            var total = _context.KorpaInfo.Where(c => c.IdKorpe1 == idKorpe)
                .Select(c => c.A.CijenaArtikla * c.KolicinaArtikla).Sum();
            return (decimal)total;
        }

        //public List<Tuple<Artikal, Recenzija, double>> PodaciOArtiklima { get => podaciOArtiklima; set => podaciOArtiklima = value; }

        [Key]
        public string IdKorpe { get => idKorpe; set => idKorpe = value; }
        public List<KorpaInfo> ArtikliKolicina { get => artikliKolicina; set => artikliKolicina = value; }

        public void DodajArtikla(Artikal artikal, int kolicina)
        {
            ArtikliKolicina.Add(new KorpaInfo(artikal, kolicina));
        }
    }
}

KorpaAppController.cs

using BestDeal.AdapteriPodataka;
using BestDeal.Models;
using BestDeal.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;

namespace BestDeal.Controllers
{
    public class KorpaAppController : Controller
    {
        private readonly IArtikli _artikliApp;
        private readonly Korpa _korpica;

        public KorpaAppController(IArtikli ak, Korpa k)
        {
            _artikliApp = ak;
            _korpica = k;
        }


        public ViewResult Index()
        {
            var items = _korpica.DajNaruceneArtikle();
            _korpica.ArtikliKolicina = items;

            var korpaPogled = new KorpaViewModel
            {
                korpa = _korpica,
                UkupnaCijena = _korpica.DajUkupnuCijenu()
            };
            return View(korpaPogled);
        }

      /*  public static void WriteErrorLog(string strErrorText)
       {
           try
           {
               //DECLARE THE FILENAME FROM THE ERROR LOG
               string strFileName = "errorLog.txt";
               string strPath = "C:\\Users\\Mirza\\Documents\\GitHub\\Grupa5-TripleDouble";
               //WRITE THE ERROR TEXT AND THE CURRENT DATE-TIME TO THE ERROR FILE
               System.IO.File.AppendAllText(strPath + "\\" + strFileName, strErrorText + " - " + DateTime.Now.ToString() + "\r\n");
           }
           catch (Exception ex)
           {
               WriteErrorLog("Error in WriteErrorLog: " + ex.Message);
           }
       }*/

        public RedirectToActionResult DodajKorpa(int artikalID)
        {
           // WriteErrorLog(artikalID.ToString());
            Artikal odabrani = _artikliApp.artikliApp.FirstOrDefault(p => p.IdArtikla == artikalID);
            if (odabrani != null)
            {
                _korpica.DodajUKorpu(odabrani, 1);
            }
            return RedirectToAction("Index");
        }

        public RedirectToActionResult BrisiKorpa(int artikalID)
        {
            var odabrani = _artikliApp.artikliApp.FirstOrDefault(p => p.IdArtikla == artikalID);
            if (odabrani != null)
            {
                _korpica.IzbaciIzKorpe(odabrani);
            }
            return RedirectToAction("Index");
        }

    }
}

Tip.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace BestDeal.Models
{
    //klasa koja omogucava dodavanje tipova
    public class Tip
    {
        public Tip()
        {
        }
        //TODO:Moguce opcije nekog IDa ili liste specificnih polja koju ima svaki tip (radi razlicitih detalja kod recenzija i sl.)
        public Tip(string ime)
        {
            Ime = ime;
        }

        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int idTipa { get; set; }
        public string Ime { get;  set; }
        public override bool Equals(object obj)
        {
            var other = obj as Tip;
            if (other == null)
            {
                return false;
            }
            return other == this;
        }

        public override int GetHashCode()
        {
            return HashCode.Combine(idTipa);
        }

        public static bool operator ==(Tip Tip1, Tip Tip2)
        {
            if (Object.ReferenceEquals(Tip1, null) && Object.ReferenceEquals(Tip2, null))
                return true;

            if (Object.ReferenceEquals(Tip1, null) || Object.ReferenceEquals(Tip2, null))
                return false;

            return Tip1.Ime == Tip2.Ime;
        }
        public static bool operator !=(Tip Tip1, Tip Tip2)
        {
            return !(Tip1 == Tip2);
        }
    }
}

KorpaInfo.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace BestDeal.Models
{
    public class KorpaInfo:Korpa
    {
        string idKorpe;
        Artikal a;
        int kolicinaArtikla;
        int idKomponente;
        public KorpaInfo()
        {
        }

        public KorpaInfo(Artikal a, int kolicinaArtikla)
        {
            this.A = a;
            this.KolicinaArtikla = kolicinaArtikla;
        }

        public KorpaInfo(string idKorpe, Artikal a, int kolicinaArtikla)
        {
            this.idKorpe = idKorpe;
            this.a = a;
            this.kolicinaArtikla = kolicinaArtikla;
        }

        public Artikal A { get => a; set => a = value; }
        public int KolicinaArtikla { get => kolicinaArtikla; set => kolicinaArtikla = value; }

        public string IdKorpe1 { get => idKorpe; set => idKorpe = value; }
    }
}

我希望在数据库中保存更改后,应用程序不会崩溃。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-11 06:39:10

对我来说,最好的解决方案是使用方法:DbContext.Attach(object),它将尝试根据相关实体的主键加载相关实体。

如果实体正在被跟踪或存在,则该方法将返回此对象。

如果不是,它将开始跟踪实体。

您还可以使用FirstOrDefault进行搜索,您将能够知道是否有任何实体具有相同的主键。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56533559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档