2012-12-04 15 views
54

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

protected override void OnModelCreating(DbModelBuilder modelBuilder) { 
    ... 
    modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); 

और फिर मैं उपयोगकर्ता के भूमिका लिंक तालिका सेट:

modelBuilder.Entity<User>() 
    .HasMany(usr => usr.Roles) 
    .WithMany(role => role.Users) 
    .Map(m => { 
     m.ToTable("UsersRoles"); 
     m.MapLeftKey("UserId"); 
     m.MapRightKey("RoleId"); 
    }); 

फिर भी जब एफई डेटाबेस बनाता है, इसके लिए एक हटाने झरना बनाता है विदेशी कुंजी संबंध, उदाहरण के लिए।

ALTER TABLE [dbo].[UsersRoles] WITH CHECK ADD CONSTRAINT [FK_dbo.UsersRoles_dbo.User_UserId] FOREIGN KEY([UserId]) 
REFERENCES [dbo].[User] ([UserId]) 
ON DELETE CASCADE 
GO 

ALTER TABLE [dbo].[UsersRoles] WITH CHECK ADD CONSTRAINT [FK_dbo.UsersRoles_dbo.Role_RoleId] FOREIGN KEY([RoleId]) 
REFERENCES [dbo].[Role] ([RoleId]) 
ON DELETE CASCADE 
GO 

मैं इस डिलीट कैस्केड को उत्पन्न करने वाले ईएफ को कैसे रोक सकता हूं?

उत्तर

93

मुझे जवाब मिला। :-) उन कैस्केड हटाए गए थे ManyToManyCascadeDeleteConvention के कारण। आप लिंक तालिकाओं के लिए यह झरना बनाने से रोकने के इस सम्मेलन को हटा देता है हटाने की जरूरत:

modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>(); 
+0

धन्यवाद इससे मुझे एक टन मदद मिली। उत्सुक, क्या आपने दोनों सम्मेलनों को हटा दिया या कई लोगों को कई सम्मेलन में हटा दिया? – kmehta

+7

दरअसल, मैंने एक-से-कई सम्मेलन को हटा दिया और इसे एक या दो इकाइयों के लिए चुनिंदा रूप से पुनः सक्षम किया। इसके बारे में मेरे नोट्स का कहना है कि, क्योंकि (एक से कई के विपरीत) आप 'WillCascadeOnDelete (true)', * सभी * का उपयोग करके कई से कई लोगों के लिए कैस्केड डिलीट को पुनः सक्षम करने के लिए फ़्लुएंट एपीआई का उपयोग नहीं कर सकते हैं। कई से अधिक टेबलों को या तो कैस्केड करना है, या कैस्केड नहीं करना है। मैंने उन्हें * सभी * कैस्केड को कम से कम बुराइयों के रूप में माना, क्योंकि ज्यादातर समय, यदि मैं कई से अधिक लिंक टेबल का उपयोग करके कुछ जुड़ा हुआ हटा देता हूं, तो मैं उन चीजों को भी चाहता हूं जिन्हें इसे हटाया जा सकता है। – Jez

+1

यह काम नहीं कर रहा था। मेरी समस्या यह है कि मेरे पास एक ही प्रकार के ऑब्जेक्ट के दो गुण होते हैं (इस उपयोगकर्ता द्वारा बनाए गए और अंतिम बार इस उपयोगकर्ता द्वारा संपादित किया गया।) मुझे उम्मीद थी कि यह "चक्र या एकाधिक कैस्केड पथों का कारण बन सकता है" त्रुटि मुझे मिल जाएगी, लेकिन यह काम नहीं किया। सुझाव? – Rogala

0

मुझे विश्वास है कि बंद ManyToManyCascadeDeleteConvention विश्व स्तर पर मोड़ एक बुद्धिमान विकल्प नहीं है। इसके बजाए, संबंधित तालिका के लिए इसे से बंद करना बेहतर है।

यह cascadeDelete संपत्ति के लिए जेनरेट माइग्रेशन फ़ाइल को संपादित करने के माध्यम से हासिल किया जा सकता है।

AddForeignKey("dbo.UsersRoles", "UserId", "dbo.User", "UserId", cascadeDelete: false);

0

मैं Ebram खलील के साथ सहमत हैं कि यह एक एकल तालिका के लिए बंद करने के लिए एक अच्छा विकल्प है: उदाहरण के लिए। मैं के रूप में मैं कर सकते हैं स्वचालित रूप से बनाया माइग्रेशन के नजदीक रहना हालांकि, की तरह है, तो मैं इसे स्थापित करेगा अप OnModelCreating में:

modelBuilder.Entity<User>() 
    .HasMany(usr => usr.Roles) 
    .WithMany(role => role.Users) 
    .Map(m => { 
     m.ToTable("UsersRoles"); 
     m.MapLeftKey("UserId"); 
     m.MapRightKey("RoleId"); 
    }) 
    .WillCascadeOnDelete(false); 

मेरा मानना ​​है कि यह दूसरी दिशा जा रहा हटाना को बरकरार रखता है, इसलिए यदि दोनों होने की जरूरत अवरुद्ध (इस उदाहरण में समझ में आता है) एक समान कॉल को Entity<User>(Role)

से शुरू करने की आवश्यकता होगी बेशक, प्रश्न पूछने के बाद यह उम्र आती है। तो यह 2012 में मान्य नहीं हो सकता है।

संबंधित मुद्दे