मैं इस अपवाद को प्राप्त किए बिना ऑर्डर को कैसे हटाऊं?

UserLicenses संदर्भ SerialOnOrderDetails और इसके विपरीत:

DELETE कथन REFERENCE बाधा "FK_SerialsOnOrderDetail_UserLicenses" का विरोध करता है। डेटाबेस "बिक्री", तालिका "dbo.SerialsOnOrderDetail", कॉलम 'UserLicenseId' में विरोध हुआ।

पुष्टि नियंत्रक कार्रवाई कोड हटाएं:

[Authorize(Roles = "admin")]    
[HttpPost, ActionName("Delete")]
public async Task<ActionResult> DeleteConfirmed(int id)
{
    Order order = GetOrderById(id);

    if (order.UserLicenses.Count > 0)
    {
        context.UserLicenses.RemoveRange(order.UserLicenses);
    }

    if (order.SerialsOnOrderDetails.Count > 0)
    {
        context.SerialsOnOrderDetails.RemoveRange(order.SerialsOnOrderDetails);
    }

    context.Orders.Remove(order);

    context.SaveChanges(); // Exception here !!!
}

[संपादित करें] लाइव डेटा जोड़ा गया

लाइव डेटा (Id = UserLicenseId):

enter image description here

अतिरिक्त कक्षाएं:

public partial class UserLicense
{   
    public string Id { get; set; }
    public int OrderId { get; set; }
    public string ProductId { get; set; }
    public int CustomerId { get; set; }
    public string AssignedUserId { get; set; }
    public bool IsActive { get; set; }

    public virtual AspNetUser AspNetUser { get; set; }
    public virtual Customer Customer { get; set; }
    public virtual Order Order { get; set; }
    public virtual Product Product { get; set; }

    public virtual ICollection<SerialsOnOrderDetail> SerialsOnOrderDetails { get; set; }
}

public partial class SerialsOnOrderDetail
{
   public int orderID { get; set; }
   public string serial { get; set; }
   public string productID { get; set; }
   public string UserLicenseId { get; set; }
   public int customerID { get; set; }

   public virtual Product Product { get; set; }
   public virtual Serial Serial1 { get; set; }
   public virtual Order Order { get; set; }
   public virtual UserLicense UserLicense { get; set; }
   public virtual Customer Customer { get; set; }
}

public partial class Order
{
    public Order()
    {
        this.OrderDetails = new HashSet<OrderDetail>();
        this.SerialsOnOrderDetails = new HashSet<SerialsOnOrderDetail>();
        this.UserLicenses = new HashSet<UserLicense>();
    }

    public int orderID { get; set; }
    public int customerID { get; set; }
    public string promoCodeID { get; set; }
    public System.DateTime date { get; set; }
    public Nullable<int> resellerID { get; set; }
    public string invoiceID { get; set; }
    public string poNumber { get; set; }
    public Nullable<System.DateTime> paymentDate { get; set; }
    public Nullable<bool> validated { get; set; }
    public string resellerOrderID { get; set; }
    public Nullable<int> parentOrderID { get; set; }
    public int months { get; set; }

    public virtual Customer Customer { get; set; }
    public virtual ICollection<OrderDetail> OrderDetails { get; set; }
    public virtual PromoCode PromoCode { get; set; }
    public virtual Reseller Reseller { get; set; }
    public virtual ICollection<SerialsOnOrderDetail> SerialsOnOrderDetails { get; set; }
    public virtual Order ParentOrder { get; set; }
    public virtual ICollection<UserLicense> UserLicenses { get; set; }
}
0
abenci 26 नवम्बर 2021, 11:55
3
यह प्रश्न आपके द्वारा उपयोग किए जाने वाले IDE से प्रभावित नहीं है, इसलिए [visual-studio] टैग यहां अप्रासंगिक है। विजुअल स्टूडियो का उपयोग करने के बारे में प्रश्नों के लिए कृपया केवल [visual-studio] टैग का उपयोग करें (जैसा कि इसके टैग विवरण द्वारा दर्शाया गया है) .
 – 
Llama
26 नवम्बर 2021, 11:57
आपने इन पंक्तियों को पहली जगह कैसे सम्मिलित किया? उनमें से एक को दूसरी पंक्ति के अस्तित्व में आने से पहले पहले डाला जाना था, इसलिए उस समय इसका संदर्भ नहीं दिया जा सकता था। सम्मिलन के दौरान जो भी तंत्र/आदेश लागू होता है, वही चरणों को हटाए जाने के दौरान विपरीत तरीके से निष्पादित करें।
 – 
Damien_The_Unbeliever
26 नवम्बर 2021, 14:15

2 जवाब

सबसे बढ़िया उत्तर

क्या आपने सत्यापित किया है कि UserLicenses और SerialsOnOrderDetails संग्रह ठीक से लोड हैं और खाली नहीं हैं? क्या आप सुनिश्चित हैं कि रिमूवरेज इसे करने का सही तरीका है? मेरा सुझाव है कि यदि आप इसके अभ्यस्त नहीं हैं तो आप EF के बारे में कुछ ट्यूटोरियल पढ़ें।

हो सकता है कि आपको इन संग्रहों को लोड करने के लिए GetOrderById को .Include("...") निर्देशों के साथ अपडेट करना होगा, या संबंधित आइटम को मैन्युअल रूप से लोड करना होगा।

0
AFract 26 नवम्बर 2021, 12:02
हां, UserLicenses संग्रह में 2 आइटम हैं जबकि SerialsOnOrderDetails 4 आइटम हैं। मुझे संदेह है कि त्रुटि इसके बजाय डीबी बाधाओं से जुड़ी है।
 – 
abenci
26 नवम्बर 2021, 12:15
1
मुझे नहीं लगता कि यह ईएफ से संबंधित है। क्या आपने पूरी तरह से प्रभावित पंक्तियों को देखने के लिए शुद्ध SQL में प्रयास किया था और यदि UserLicense को हटाने के लिए किसी अन्य SerialsOnOrderDetail (उदाहरण के लिए) में उपयोग नहीं किया जाता है? यह बाधा उल्लंघन की व्याख्या करेगा।
 – 
AFract
26 नवम्बर 2021, 13:09
मैंने लाइव डेटा जोड़ने के लिए अभी ओपी संपादित किया है, क्या यह समस्या को समझने में मदद करता है?
 – 
abenci
26 नवम्बर 2021, 14:13
और क्या आपने सत्यापित किया है कि इनमें से कोई भी उपयोगकर्ता लाइसेंस किसी अन्य SerialsOnOrderDetails रिकॉर्ड में उपयोग नहीं किया गया है? आपका स्क्रीनशॉट यह नहीं बताता है क्योंकि यह ऑर्डर पर केंद्रित है न कि पंक्तियों को स्वयं को हटाने के लिए। साथ ही, जैसा कि पहले ही सुझाव दिया गया है, शुद्ध एसक्यूएल में हटाने का प्रयास करें (अंत में रोलबैक के साथ लेनदेन में यदि आप वास्तव में पंक्तियों को हटाना नहीं चाहते हैं)।
 – 
AFract
26 नवम्बर 2021, 14:21
हाँ, UserLicenseId gx2rdtch का उपयोग 104458 क्रम में भी किया जाता है। यह रिकॉर्ड हटाने में त्रुटि की व्याख्या करता है।
 – 
abenci
26 नवम्बर 2021, 14:47

आपके द्वारा उद्धृत वह बाधा संदेश अंतर्निहित SQL सर्वर से है। यह एक ईएफ त्रुटि नहीं है, यह पारित हो गया है।

जब मुझे टीएसक्यूएल में इस तरह की समस्या मिलती है तो समाधान आम तौर पर एक ही लेनदेन में पारस्परिक रूप से संदर्भित पंक्तियों को हटाने के लिए होता है।

जबकि मैं ईएफ से बहुत परिचित नहीं हूं, एक त्वरित खोज प्रति ऑपरेशन एक लेनदेन के डिफ़ॉल्ट व्यवहार के बजाय एकाधिक लेनदेन को एक लेनदेन संबंधी संदर्भ में डालने के इस उदाहरण को बदल देती है।

{
    context.Database.Log = Console.WriteLine;
    using (DbContextTransaction transaction = context.Database.BeginTransaction())
    {
        try
        {
            Author author1 = new Author() {    Name = "Mark" };
            Author author2 = new Author() {    Name = "John" };
            
            context.Authors.Add(author1);
            context.SaveChanges();
            
            context.Authors.Add(author2);
            context.SaveChanges();
            transaction.Commit();
        }
        catch (Exception ex)
        {
            transaction.Rollback();
        }
    }
}

मैंने देखा कि एक अन्य प्रतिवादी अन्य चीजों का वर्णन करता है जो गलत हो सकती हैं। यह पूरी तरह से संभव है कि हम दोनों सही हों और हल करने के लिए कई मुद्दे हैं।

0
Peter Wone 26 नवम्बर 2021, 12:07
नहीं, अनेक context.SaveChanges() कॉल जोड़ने से भी कोई सहायता नहीं मिलती, क्षमा करें।
 – 
abenci
26 नवम्बर 2021, 12:18
आप दोनों पंक्तियों को एक ही समय में केवल तभी हटा सकते हैं जब वे एक ही तालिका में संग्रहीत हों। अन्यथा, यह कोई मदद नहीं है क्योंकि SQL सर्वर विदेशी चाबियों पर आस्थगित चेक का समर्थन नहीं करता है (जो, अन्य उत्पादों में, केवल लेन-देन के प्रतिबद्ध होने पर चेक होने की अनुमति देगा)। आपके पास दो कथनों को दो तालिकाओं को प्रभावित करने वाले होने चाहिए और पहले कथन के साथ त्रुटि होगी।
 – 
Damien_The_Unbeliever
26 नवम्बर 2021, 14:19