कई एंटिटी फ्रेमवर्क में कई डालें / अपडेट करें। मैं यह कैसे करुं?


104

मैं EF4 का उपयोग कर रहा हूं और इसके लिए नया हूं। मेरी परियोजना में मेरे पास बहुत से हैं और सम्मिलित करने या अद्यतन करने के लिए काम नहीं कर सकते। मैंने सिर्फ एक छोटा प्रोजेक्ट बनाया है, यह देखने के लिए कि इसे कैसे कोडित किया जाना चाहिए।

मान लीजिए कि मेरे पास 3 टेबल हैं

  1. वर्ग: ClassID-ClassName
  2. छात्र: StudentID-FirstName-Surname
  3. स्टूडेंटक्लास: स्टूडेंट-क्लासिड

सभी संबंध जोड़ने और मॉडल ब्राउज़र के माध्यम से मॉडल को अपडेट करने के बाद मैंने देखा है कि स्टूडेंटक्लास दिखाई नहीं देता है, यह डिफ़ॉल्ट व्यवहार प्रतीत होता है।

अब मुझे एक इन्सर्ट और अपडेट दोनों करने की जरूरत है। आप इसे कैसे करते हो? कोई भी कोड सैंपल या लिंक जहां मैं एक उदाहरण डाउनलोड कर सकता हूं, या आप 5 मिनट अतिरिक्त कर सकते हैं?

जवाबों:


139

संस्थाओं (या वस्तुओं) के संदर्भ में आपके पास एक ऐसी Classवस्तु है जिसका एक संग्रह है Studentsऔर एक ऐसी Studentवस्तु है जिसका संग्रह है Classes। चूंकि आपकी StudentClassतालिका में केवल Ids और कोई अतिरिक्त जानकारी नहीं है, इसलिए EF ज्वाइनिंग टेबल के लिए एक इकाई नहीं बनाता है। यह सही व्यवहार है और यही आप उम्मीद करते हैं।

अब, आवेषण या अपडेट करते समय, वस्तुओं के संदर्भ में सोचने की कोशिश करें। उदाहरण के लिए, यदि आप दो छात्रों के साथ एक कक्षा सम्मिलित करना चाहते हैं, तो Classऑब्जेक्ट बनाएं, ऑब्जेक्ट्स, Studentछात्रों को कक्षा Studentsसंग्रह में जोड़ें Classऑब्जेक्ट को संदर्भ और कॉल में जोड़ें SaveChanges:

using (var context = new YourContext())
{
    var mathClass = new Class { Name = "Math" };
    mathClass.Students.Add(new Student { Name = "Alice" });
    mathClass.Students.Add(new Student { Name = "Bob" });

    context.AddToClasses(mathClass);
    context.SaveChanges();
}

यह Classतालिका में एक प्रविष्टि, तालिका में दो प्रविष्टियाँ Studentऔर तालिका में दो प्रविष्टियों StudentClassको एक साथ जोड़ देगा।

आप मूल रूप से अपडेट के लिए भी ऐसा ही करते हैं। बस डेटा प्राप्त करें, संग्रह से वस्तुओं को जोड़कर और हटाकर ग्राफ को संशोधित करें, कॉल करें SaveChanges। विवरण के लिए इस तरह के प्रश्न की जांच करें

संपादित करें :

आपकी टिप्पणी के अनुसार, आपको एक नया सम्मिलित करने Classऔर उसमें दो मौजूदा जोड़ने की आवश्यकता Studentsहै:

using (var context = new YourContext())
{
    var mathClass= new Class { Name = "Math" };
    Student student1 = context.Students.FirstOrDefault(s => s.Name == "Alice");
    Student student2 = context.Students.FirstOrDefault(s => s.Name == "Bob");
    mathClass.Students.Add(student1);
    mathClass.Students.Add(student2);

    context.AddToClasses(mathClass);
    context.SaveChanges();
}

चूंकि दोनों छात्र पहले से ही डेटाबेस में हैं, इसलिए उन्हें सम्मिलित नहीं किया जाएगा, लेकिन चूंकि अब वे Studentsसंग्रह में हैं Class, इसलिए StudentClassतालिका में दो प्रविष्टियां डाली जाएंगी ।


नमस्ते, आपके उत्तर के लिए धन्यवाद। मेरा परिदृश्य यह है कि मुझे कक्षा में 1 प्रविष्टि डालने की आवश्यकता है और आपके उदाहरण के रूप में स्टूडेंटक्लास में 2 प्रविष्टियाँ और छात्र में कोई प्रविष्टि नहीं है। मैं भ्रमित हूँ कि मैं कैसे करूँ
user9969

इस TREAT को अपडेट किया गया। अद्यतन के बारे में। मुझे कुछ भी विशेष करने की आवश्यकता है? उदाहरण के लिए className को अद्यतन करना।
user9969

3
यह डेटाबेस से उन वस्तुओं को जोड़ने के लिए एक उपरिशायी जोड़ देगा जिन्हें आइटम को जोड़ना है। अटैच विधि का उपयोग केवल संबंध जोड़ने के लिए किया जा सकता है। देखें msdn.microsoft.com/en-us/data/jj592676.aspx और भी stackoverflow.com/questions/11355019/...
Gnomo

3
AddToClasses कक्षा के लिए DbSet है?
जो स्मो

1
क्लास और स्टूडेंट के लिए कंस्ट्रक्टर्स में अपने कलेक्शन को इनिशियलाइज़ करना न भूलें। उदाहरण के लिए: पब्लिक क्लास () {this.Students = new HashSet <Student> (); }
user1040323

40

अद्यतन करने के लिए इसे आज़माएँ:

[HttpPost]
public ActionResult Edit(Models.MathClass mathClassModel)
{
    //get current entry from db (db is context)
    var item = db.Entry<Models.MathClass>(mathClassModel);

    //change item state to modified
    item.State = System.Data.Entity.EntityState.Modified;

    //load existing items for ManyToMany collection
    item.Collection(i => i.Students).Load();

    //clear Student items          
    mathClassModel.Students.Clear();

    //add Toner items
    foreach (var studentId in mathClassModel.SelectedStudents)
    {
        var student = db.Student.Find(int.Parse(studentId));
        mathClassModel.Students.Add(student);
    }                

    if (ModelState.IsValid)
    {
       db.SaveChanges();
       return RedirectToAction("Index");
    }

    return View(mathClassModel);
}

इसने मेरा दिन बचाया धन्यवाद !!! वे आइटम होने के लिए महत्वपूर्ण हिस्सा हैं। कॉलेक्शन (i => i.Students) .Load (); भाग
गेरी प्रीटोरियस

बस एक साइड नोट, जब ऐसा करने के दौरान मेरे पास एक InvalidOperationException थी, तो मेरी इकाई जैसा कुछ भी संदर्भ में मौजूद नहीं था। मैंने सिर्फ संदर्भ के लिए कहा। इससे निपटने के लिए।
किलाजुर

कभी नहीं पता लगा होगा कि बाहर। अनेक अनेक धन्यवाद।
जारेड बीच

1
मुझे यहां अपना धन्यवाद जोड़ने की अनुमति दें। मैंने इस कार्य को पूरा करने के लिए पिछले 4 दिनों में कोड की 130 से अधिक पंक्तियों को लिखा और परीक्षण किया, लेकिन ऐसा नहीं कर सका। इस की कोशिश की और चीजों को पूरी तरह से काम किया। जबकि मुझे आइटम वेरिएबल को स्थापित करने का उद्देश्य समझ में नहीं आता है और फिर इसका उपयोग बिल्कुल नहीं किया जाता है, मुझे खुशी है कि यह काम करता है! धन्यवाद एक लाख बाजिलयन !!!! :)
ड्यूड-डस्टिक

सवाल डालने और अद्यतन करने पर विचार करते हुए, यह उत्तर प्रश्न और स्वीकृत उत्तर को पूरा करता है। आपका बहुत बहुत धन्यवाद!
विक्स

5

मैं उस पर अपना अनुभव जोड़ना चाहता था। वास्तव में EF, जब आप किसी ऑब्जेक्ट को संदर्भ में जोड़ते हैं, तो यह सभी बच्चों की स्थिति और संबंधित संस्थाओं को जोड़ा जाता है। यद्यपि यहां नियम में एक छोटा अपवाद है: यदि बच्चों / संबंधित संस्थाओं को एक ही संदर्भ से ट्रैक किया जा रहा है, तो ईएफ यह समझता है कि ये संस्थाएं मौजूद हैं और उन्हें नहीं जोड़ती हैं। समस्या तब होती है जब उदाहरण के लिए, आप बच्चों / संबंधित संस्थाओं को किसी अन्य संदर्भ या वेब यूआई आदि से लोड करते हैं और फिर हाँ, ईएफ इन संस्थाओं के बारे में कुछ भी नहीं जानता है और उन सभी को जोड़ता है। उससे बचने के लिए, बस संस्थाओं की कुंजी प्राप्त करें और उन्हें खोजें (जैसे context.Students.FirstOrDefault(s => s.Name == "Alice"))उसी संदर्भ में जिसमें आप अतिरिक्त करना चाहते हैं।


3

मैं कई-से-कई संबंधों को संभालने के लिए निम्नलिखित तरीके का उपयोग करता हूं जहां केवल विदेशी चाबियाँ शामिल हैं।

तो डालने के लिए :

public void InsertStudentClass (long studentId, long classId)
{
    using (var context = new DatabaseContext())
    {
        Student student = new Student { StudentID = studentId };
        context.Students.Add(student);
        context.Students.Attach(student);

        Class class = new Class { ClassID = classId };
        context.Classes.Add(class);
        context.Classes.Attach(class);

        student.Classes = new List<Class>();
        student.Classes.Add(class);

        context.SaveChanges();
    }
}

के लिए हटाने ,

public void DeleteStudentClass(long studentId, long classId)
{
    Student student = context.Students.Include(x => x.Classes).Single(x => x.StudentID == studentId);

    using (var context = new DatabaseContext())
    {
        context.Students.Attach(student);
        Class classToDelete = student.Classes.Find(x => x.ClassID == classId);
        if (classToDelete != null)
        {
            student.Classes.Remove(classToDelete);
            context.SaveChanges();
        }
    }
}

1

एंटिटी फ्रेमवर्क में, जब ऑब्जेक्ट को संदर्भ में जोड़ा जाता है, तो इसकी स्थिति जोड़ी में बदल जाती है। EF ऑब्जेक्ट ट्री में जोड़े गए प्रत्येक ऑब्जेक्ट की स्थिति को भी बदलता है और इसलिए आपको या तो प्राथमिक कुंजी उल्लंघन त्रुटि मिल रही है या तालिका में डुप्लिकेट रिकॉर्ड जोड़े जाते हैं।


2
कृपया पर्याप्त विवरण देने के लिए संपादित करें ताकि उपयोगकर्ता को उत्तर पाने के लिए आपके ब्लॉग पर न आना पड़े।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.