2012-09-17 11 views
69

मैंने ASP.NET MVC application में अपने मॉडल में से किसी एक को [Required] डेटा एनोटेशन जोड़ा है। एक प्रवास का निर्माण, निम्न त्रुटि में Update-Database आदेश परिणाम चलाने के बाद:इकाई फ्रेमवर्क माइग्रेशन में आवश्यक फ़ील्ड के लिए डिफ़ॉल्ट मान?

Cannot insert the value NULL into column 'Director', table 'MOVIES_cf7bad808fa94f89afa2e5dae1161e78.dbo.Movies'; column does not allow nulls. UPDATE fails. The statement has been terminated.

यह उनकी Director कॉलम में शून्य होने कुछ रिकॉर्ड के कारण है। मैं उन मानों को स्वचालित रूप से कुछ डिफ़ॉल्ट रूप से कैसे बदल सकता हूं ("जॉन डो" कहें) निदेशक?

public class Movie 
    { 
     public int ID { get; set; } 
     [Required] 
     public string Title { get; set; } 

     [DataType(DataType.Date)] 
     public DateTime ReleaseDate { get; set; } 

     [Required] 
     public string Genre { get; set; } 

     [Range(1,100)] 
     [DataType(DataType.Currency)] 
     public decimal Price { get; set; } 

     [StringLength(5)] 
     public string Rating { get; set; } 

     [Required]  /// <--- NEW 
     public string Director { get; set; } 
    } 

यहाँ है मेरी नवीनतम प्रवास और:

यहाँ मेरी मॉडल है

public partial class AddDataAnnotationsMig : DbMigration 
{ 
    public override void Up() 
    { 
     AlterColumn("dbo.Movies", "Title", c => c.String(nullable: false)); 
     AlterColumn("dbo.Movies", "Genre", c => c.String(nullable: false)); 
     AlterColumn("dbo.Movies", "Rating", c => c.String(maxLength: 5)); 
     AlterColumn("dbo.Movies", "Director", c => c.String(nullable: false)); 
    } 

    public override void Down() 
    { 
     AlterColumn("dbo.Movies", "Director", c => c.String()); 
     AlterColumn("dbo.Movies", "Rating", c => c.String()); 
     AlterColumn("dbo.Movies", "Genre", c => c.String()); 
     AlterColumn("dbo.Movies", "Title", c => c.String()); 
    } 
} 

उत्तर

52

अगर मैं सही ढंग से याद, कुछ इस तरह काम करना चाहिए:

AlterColumn("dbo.Movies", "Director", c => c.String(nullable: false, defaultValueSql: "John Doe")); 
+7

मैं इतना भी सोचा, लेकिन यह है कि मौजूदा रिकॉर्ड के लिए काम करते प्रतीत नहीं होता। तो मुझे अभी भी एक त्रुटि मिलती है। – drozzy

+0

@drozzy शायद यह बग है, जैसा कि यहां है: [ईएफ 4.3.1 माइग्रेशन अपवाद - AlterColumn defaultValueSql अलग-अलग तालिकाओं के लिए एक ही डिफ़ॉल्ट बाधा नाम बनाता है] (http://stackoverflow.com/questions/9830216/ef-4-3-1 -माइग्रेशन-अपवाद-अल्टरकॉलम- defaultvaluesql-creates-same-default /) आप अपनी क्वेरी द्वारा 'IS NULL' चेक के साथ पंक्तियां अपडेट कर सकते हैं। – webdeveloper

+0

दिलचस्प है, लेकिन मुझे यकीन नहीं है कि मैं समझता हूं कि वे किस बारे में बात कर रहे हैं। हालांकि, अगर यह एक बग है, तो हाँ, यह समझ में आता है। – drozzy

9
public partial class AddDataAnnotationsMig : DbMigration 
{ 
    public override void Up() 
    { 
     AlterColumn("dbo.Movies", "Title", c => c.String(nullable: false,defaultValue:"MyTitle")); 
     AlterColumn("dbo.Movies", "Genre", c => c.String(nullable: false,defaultValue:"Genre")); 
     AlterColumn("dbo.Movies", "Rating", c => c.String(maxLength: 5)); 
     AlterColumn("dbo.Movies", "Director", c => c.String(nullable: false,defaultValue:"Director")); 

    } 

    public override void Down() 
    {  
     AlterColumn("dbo.Movies", "Director", c => c.String()); 
     AlterColumn("dbo.Movies", "Rating", c => c.String()); 
     AlterColumn("dbo.Movies", "Genre", c => c.String()); 
     AlterColumn("dbo.Movies", "Title", c => c.String());  
    } 
} 
+2

उम ... धन्यवाद, लेकिन यह @ वेब डेवलपर के उत्तर से अलग कैसे है? – drozzy

+1

यह आपको नहीं बताया गया है कि आपको डिफ़ॉल्ट मान पैरामीटर – Pushpendra

+1

@ पुष्पेन्द्र जोड़ने के लिए कहां है, यह मजाकिया है कि डेवलपर्स कैसे भूल जाते हैं कि एक समय पर, उन्हें बहुत कुछ नहीं पता था। मुझे विस्तृत उत्तरों पसंद हैं जो सभी स्तरों को पूरा करते हैं। बहुत ही उत्तम कार्य! – usefulBee

92

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

public override void Up() 
{ 
    Sql("UPDATE [dbo].[Movies] SET Title = 'No Title' WHERE Title IS NULL"); 
    AlterColumn("dbo.Movies", "Title", c => c.String(nullable: false,defaultValue:"MyTitle")); 
} 

इसका कारण यह है AlterColumn तालिका विनिर्देश में कुछ विशिष्ट मूल्य के लिए स्तंभ का डिफ़ॉल्ट सेट करने के लिए DDL उत्पादन होता है। डीडीएल डेटाबेस में मौजूदा पंक्तियों को प्रभावित नहीं करता है।

आप वास्तव में एक ही समय में दो बदलाव कर रहे हैं (डिफ़ॉल्ट सेट कर रहे हैं और कॉलम न्यूल बना रहे हैं) और उनमें से प्रत्येक व्यक्तिगत रूप से मान्य है, लेकिन चूंकि आप दोनों एक ही समय में बना रहे हैं, तो आप उम्मीद कर सकते हैं 'समझदारी से' प्रणाली को आपके इरादे का एहसास है और सभी NULL मानों को डिफ़ॉल्ट मान पर सेट करें, लेकिन यह हर समय अपेक्षित नहीं है।

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

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

+11

Google के माध्यम से इस उत्तर को ढूंढने वाले लोगों के लिए: मैंने अभी यह ईएफ 6 में कोशिश की है और अद्यतन कथन आवश्यक नहीं है (अब)। मुझे लगता है कि वे इसे सब के बाद एक बग माना जाता है। – EPLKleijntjens

+1

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

+1

स्पष्टीकरण पर स्पॉट। AlterColumn() बस कॉलम परिभाषा बदलता है। यह मौजूदा रिकॉर्ड को प्रभावित नहीं करता है – Korayem

5

यकीन नहीं करता है, तो इस विकल्प को हमेशा के आसपास थी लेकिन सिर्फ वही समस्या में भाग में पाया गया कि मैं उपयोग कर किसी भी मैन्युअल अपडेट चलने के बिना डिफ़ॉल्ट मान सेट करने के लिए निम्न

defaultValueSql: "'NY'"

मैं एक मिल गया में सक्षम था त्रुटि मान "NY" तो था मैं महसूस किया कि वे उम्मीद कर रहे हैं "GETDATE()" की तरह एक एसक्यूएल मूल्य तो मैं करने की कोशिश की "'NY'" और है कि चाल

पूरी पंक्ति इस

तरह लग रहा है किया this answer को 0

AddColumn("TABLE_NAME", "State", c => c.String(maxLength: 2, nullable: false, defaultValueSql: "'NY'"));

धन्यवाद, मुझे सही रास्ते

1

मैंने पाया कि सिर्फ इकाई संपत्ति पर स्वत: संपत्ति प्रारंभकर्ता का उपयोग कर काम कर पाने के लिए पर्याप्त है पर मिला है।

उदाहरण के लिए:

public class Thing { 
    public bool IsBigThing { get; set; } = false; 
} 
+0

यह एक अच्छा जवाब है (मेरी मदद की), लेकिन यह डेटाबेस में डिफ़ॉल्ट मान नहीं जोड़ता है, यह कोड में मान सेट करता है। – chris31389

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