एकाधिक जोड़े गए संस्थानों में एक ही प्राथमिक कुंजी हो सकती है


81

यहाँ 3 संस्थाओं का मेरा मॉडल है: मार्ग, स्थान और स्थान- InRoute।
नमूना

निम्न विधि विफल हो जाती है और जब यह हो तो अपवाद प्राप्त करें:

 public static Route InsertRouteIfNotExists(Guid companyId, IListLocation> locations)
        {
            //Loop on locations and insert it without commit
            InsertLocations(companyId, routesOrLocations);

            RouteRepository routeRep = new RouteRepository();
            Route route = routeRep.FindRoute(companyId, locations);
            if (route == null)
            {
                route = new Route()
                {
                    CompanyId = companyId,
                    IsDeleted = false
                };
                routeRep.Insert(route);
                LocationInRouteRepository locInRouteRep = new LocationInRouteRepository();
                for (int i = 0; i < locations.Count; i++)
                {
                    locInRouteRep.Insert(new LocationInRoute()
                    {
                        //Id = i,
                        LocationId = locations[i].Id,
                        Order = i,
                        RouteId = route.Id
                    });
                }
            }
            return route;
        }

जब कर:

InsertRouteIfNotExists(companyId, locations);
UnitOfWork.Commit();

मुझे मिला:

'SimTaskModel.FK_T_STF_SUB_LOCATION_IN_ROUTE_T_STF_LOCATION_location_id' संबंध का प्रमुख अंत निर्धारित करने में असमर्थ। एकाधिक जोड़े गए संस्थानों में एक ही प्राथमिक कुंजी हो सकती है।

जब कमेट को विभाजित करते हैं और मेथोस में सम्मिलित करते हैं - यह काम करता है:

  public static Route InsertRouteIfNotExists(Guid companyId, IListLocation> locations)
            {
                //Loop on locations and insert it without commit
                InsertLocations(companyId, routesOrLocations);
                UnitOfWork.Commit();

                RouteRepository routeRep = new RouteRepository();
                Route route = routeRep.FindRoute(companyId, locations);
                if (route == null)
                {
                    route = new Route()
                    {
                        CompanyId = companyId,
                        IsDeleted = false
                    };
                    routeRep.Insert(route);
                    LocationInRouteRepository locInRouteRep = new LocationInRouteRepository();
                    for (int i = 0; i < locations.Count; i++)
                    {
                        locInRouteRep.Insert(new LocationInRoute()
                        {
                            //Id = i,
                            LocationId = locations[i].Id,
                            Order = i,
                            RouteId = route.Id
                        });
                    }
                    UnitOfWork.Commit();
                }
                return route;
            }

मैं विधि के बाहर और भीतर एक बार कॉल करना चाहूंगा। यह पहले उदाहरण में क्यों विफल हो जाता है और इसका अपवाद क्या है?


9
@Ladislav Mrnka: मेरा कोई मालिक नहीं है और यह मेरा प्रोजेक्ट है। मैं वास्तव में नहीं जानता कि आपको कहां से आभास होता है कि मैं तुरंत एसओ से पूछता हूं। आप पूरे दिन कंप्यूटर का उपयोग करने वाले एकमात्र व्यक्ति नहीं हैं। मुफ्त के लिए परामर्श? क्या कोई किसी को उसके उत्तरों की गारंटी देता है? मेरा मानना ​​है कि यह एक मंच है, जहां प्रश्न यहां पूछे जा सकते हैं और यही मैं कर रहा हूं। मेरे पास कई सवाल हैं और मेरा मानना ​​है कि मैं इस मंच और आपके जैसे लोगों के लिए धन्यवाद सीखने की लंबी दूरी तय करता हूं। भागीदारी एक विकल्प है।
नौर

1
@ लादिस्लाव: मैं केवल यथोचित अच्छी तरह से पूछा गया प्रश्न देखता हूं, और ओपी का प्रोफाइल शीर्ष पर या तो कुछ भी इंगित नहीं करता है।
हेंक होल्टरमैन

क्या आप ऑपरेशन के पूरे दायरे में एक ही ObjectContext का उपयोग कर रहे हैं या प्रत्येक नए रिपॉजिटरी का अपना ObjectContext होगा?
आकाश कावा

@ आकाश कावा: मैं उसी ObjectContext का उपयोग कर रहा हूं।
नोर

जवाबों:


144

त्रुटि एक विदेशी कुंजी आईडी (संदर्भ के विपरीत) के कारण होती है जिसे हल नहीं किया जा सकता है। आपके मामले में, आपके पास एक LocationInRole है जो 0. के आईडी के साथ किसी स्थान का संदर्भ देता है। इस आईडी के साथ कई स्थान हैं।

स्थान को अभी तक एक आईडी नहीं दी गई है क्योंकि वे अभी तक डेटाबेस में सहेजे नहीं गए हैं जो कि आईडी उत्पन्न होने पर होता है। आपके दूसरे उदाहरण में, उनके आईडी तक पहुंचने से पहले स्थान सहेजे जाते हैं, यही वजह है कि यह काम करता है।

यदि आप केवल बाद में SaveChanges करना चाहते हैं, तो आप रिश्तों को परिभाषित करने के लिए स्थान ID पर भरोसा नहीं कर पाएंगे।

निम्नलिखित पंक्ति स्वैप करें ...

LocationId = locations[i].Id

...इसके लिए...

Location = locations[i]

रिश्ते तब ऑब्जेक्ट संदर्भों पर आधारित होंगे जो कि स्थान-निर्धारण पर निर्भर नहीं हैं।


क्या आप में से कोई भी मेरे पोस्ट को देख सकता है और मुझे बता सकता है कि मैं इसे कैसे ठीक कर सकता हूं, मुझे एक ही मुद्दा मिल रहा है : stackoverflow.com/questions/26783934/… मैं इसकी सराहना करता हूं!
duxfox--

मैं इस त्रुटि हो रही है जब मैं env परीक्षण करने के लिए तैनात ... नहीं देव en किसी भी विचार environemnet में?
तरण

@Taran यदि कोड समान है और आप दोनों वातावरणों में परीक्षण करने के लिए एक ही प्रक्रिया का उपयोग कर रहे हैं (मैं इन बिंदुओं की जांच करूंगा) तो यह अजीब लगता है। हो सकता है कि आप देव में केवल एक ही स्थान जोड़ रहे हों (उदाहरण के साथ यहाँ पर)? कम से कम दो जोड़ने की कोशिश करें।
स्कॉट मुनरो

मेरी समस्या इस एक का रूपांतर हो सकती है। मैं स्पष्ट रूप से बच्चों पर माता-पिता की संपत्ति को स्थापित किए बिना बच्चे की वस्तुओं को माता-पिता के संग्रह में जोड़ रहा था। मुझे उम्मीद थी कि ईएफ इसे हल कर सकता है, लेकिन ओपी के समान त्रुटि प्राप्त हुई जब तक कि मैंने स्पष्ट रूप से बच्चे पर मूल संपत्ति निर्धारित नहीं की। आशा है कि यह किसी की मदद करता है।
एरिक एच

4

यदि यह भविष्य के पाठकों के लिए किसी काम का है, तो मेरे मामले में यह त्रुटि मेरे डेटाबेस में गलत तरीके से कॉन्फ़िगर की गई विदेशी कुंजी (और DB से उत्पन्न मॉडल) के कारण थी।

मेरे पास टेबल थी:

Parent (1-1) Child (1-many) Grandchild

और ग्रैंडचिल्ड टेबल ने अनजाने में माता-पिता (बच्चे) तक एक विदेशी कुंजी प्राप्त कर ली थी और यह दादा-दादी (माता-पिता) था। कई पेरेंट संस्थाओं को नए से बचाने पर, मुझे यह त्रुटि मिली। विदेशी कुंजी को ठीक करने के लिए फिक्स किया गया है।


मेरे मामले में (मैंने बेवकूफी से) अपनी प्राथमिक कुंजी आधार तालिका को अपनी विदेशी कुंजी आधार तालिका और मेरी प्राथमिक कुंजी कॉलम के समान ही सेट किया था क्योंकि मेरा विदेशी कुंजी कॉलम शर्म की बात है कि यह किसी की मदद करता है।
डेव

3

एक ही त्रुटि में चलाने से मुझे अत्यधिक संदेह है कि वास्तविक मुद्दा स्थान की परिभाषा थी। सीधे शब्दों में कहें, ईएफ कोड में सबसे पहले मैंने शर्त लगाई कि यह इस तरह दिखाई देगा:

public class Location
{
    public int Id { get; set; }
    ...
    public Location ParentLocation { get; set; }
    [ForeignKey("ParentLocation")]
    public int ParentLocationId { get; set; }
}

दूसरे शब्दों में, प्रश्न में, पेरेंटलोकेशन / पेरेंटलोकेशनआईडी इस तालिका में एक पुनरावर्ती संदर्भ है।

ParentLocationId अशक्त नहीं है। इसका मतलब है कि यह एक 0 के साथ डाला जा रहा है, और जब आप माइग्रेट करते हैं, तो EF इन्सर्ट पर शिकायत करेगा - भले ही सच्चाई यह है कि एक बार माइग्रेशन आपके पास एक टेबल है EF आपको कभी भी सम्मिलित नहीं होने देगा।

एक ही तालिका के काम पर वापस एक पुनरावर्ती संदर्भ बनाने का एकमात्र तरीका पुनरावर्ती संदर्भ को अशक्त बनाना है:

public class Location
{
    public int Id { get; set; }
    ...
    public Location ParentLocation { get; set; }
    [ForeignKey("ParentLocation")]
    public int? ParentLocationId { get; set; }
}

के ?बाद नोट करें int


यदि आप चाइल्ड लोकेशन बनाने से पहले पेरेंट लोकेशन पर SaveChanges करते हैं तो क्या पुराना (नॉलेबल) वर्जन काम नहीं करेगा?
एंड्रे कोप्स

1
ऊपर ध्यान न दें, मैं एक मूर्ख हूँ। आप पहला स्थान नहीं बना पाएंगे।
एंड्रे कोप्स

कार्डिनैलिटी की समस्या थी। सही बात।
aclalex

0

इस अपवाद को खोजने वालों के लिए:
मेरे मामले में, यह आवश्यक नेविगेशन प्रॉपर्टी सेट करने में विफल रहा।

public class Question
{
    //...
    public int QuestionGridItemID { get; set; }
    public virtual QuestionGridItem GridItem { get; set; }
    //...
    public int? OtherQuestionID { get; set; }
    public Question OtherQuestion { get; set; }
}

//...

question.OtherQuestion = otherQuestion;
questionGridItem.Questions.Add(question);
dataContext.SaveChanges(); //fails because otherQuestion wasn't added to 
//any grid item's Question collection

0

मुझे भी यही समस्या थी। मेरे लिए हल परिदृश्य के साथ। मुझे लगता है कि आपको नीचे अपना कोड बदलना होगा:

var insertedRoute =routeRep.Insert(route);
.....
insertedRoute.LocationInRoute = new List<LocationInRoute>();
for(....){
    var lInRoute = new LocationInRoute(){
    ....
    Route=insertedRoute;
}

insertedRoute.LocationInRoute.Add(lInRoute );
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.