Entity Framework geçişlerinde Gerekli alanlar için varsayılan değer?


93

[Required]Veri açıklamasını bir ASP.NET MVC uygulamasındaki modellerimden birine ekledim . Bir geçiş oluşturduktan sonra, Update-Databasekomutun çalıştırılması aşağıdaki hatayla sonuçlanır:

NULL değeri 'Director' sütununa, 'MOVIES_cf7bad808fa94f89afa2e5dae1161e78.dbo.Movies' tablosuna eklenemiyor; sütun boş değerlere izin vermez. UPDATE başarısız. Açıklama sona erdirildi.

Bu, Directorsütunlarında NULL bulunan bazı kayıtlardan kaynaklanmaktadır . Bu değerleri otomatik olarak bir varsayılan (örneğin "John Doe") yönetmenle değiştirebilirim?

İşte modelim:

  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; }
    }

ve işte son geçişim:

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());
    }
}

Yanıtlar:


74

Doğru hatırlıyorsam, bunun gibi bir şey çalışmalı:

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

Not: defaultValueSql parametre değeri, birebir SQL ifadesi olarak değerlendirilir, bu nedenle gerekli değer, John Doe örneği gibi etkin bir şekilde bir dizeyse, değerin etrafında tek tırnak işaretleri gerekir.


9
Ben de öyle düşündüm, ancak bu mevcut kayıtlar için işe yaramıyor. Bu yüzden hala bir hata alıyorum.
Andriy Drozdyuk

@drozzy Belki bir hata, şuradaki gibi: EF 4.3.1 Geçiş İstisnası - AlterColumn defaultValueSql, farklı tablolar için aynı varsayılan kısıtlama adını oluştururIS NULL Sorgunuzla kontrol ederek satırları güncelleyebilirsiniz .
webdeveloper

İlginç, ama ne hakkında konuştuklarını anladığımdan emin değilim. Ancak, bu bir hata ise, o zaman evet, mantıklı olacaktır.
Andriy Drozdyuk

6
Sanırım şöyle olmalı: "'John Doe'"- SQL alıntıları kullanmanız gerekiyor.
Sean

1
@webdeveloper, bir hata olduğunu düşünmüyorum, neden AlterColumnmevcut değerleri güncelleyelim? Bu bir DDL (DML değil) komutudur.
Anton

110

@Webdeveloper ve @Pushpendra'dan gelen cevaba ek olarak, mevcut satırları güncellemek için geçişinize manuel olarak güncelleme eklemeniz gerekir. Örneğin:

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"));
}

Bunun nedeni AlterColumn, sütunun varsayılanını tablo spesifikasyonundaki belirli bir değere ayarlamak için DDL üretmesidir. DDL, veritabanındaki mevcut satırları etkilemez.

Aslında aynı anda iki değişiklik yapıyorsunuz (varsayılanı ayarlayıp sütunu BOŞ DEĞİL yapıyorsunuz) ve her biri ayrı ayrı geçerlidir, ancak ikisini aynı anda yaptığınız için, sistemin ' akıllıca 'amacınızı gerçekleştirin ve tüm NULLdeğerleri varsayılan değere ayarlayın, ancak bu her zaman beklenen şey değildir.

Diyelim ki sütun için yalnızca varsayılan değeri ayarlıyorsunuz ve onu BOŞ DEĞİL yapmıyorsunuz. Açıkçası, tüm NULL kayıtlarının sağladığınız varsayılanla güncellenmesini beklemiyorsunuz.

Bu yüzden, bence bu bir hata değil ve EF'in verilerimi açık bir şekilde yapmasını söylemediğim şekillerde güncellemesini istemiyorum. Geliştirici, sisteme verilerle ne yapılacağı konusunda talimat vermekten sorumludur.


17
Bu cevabı google aracılığıyla bulan insanlar için: Bunu EF6'da denedim ve güncelleme ifadesi artık gerekli görünmüyor. Sanırım bunu bir hata olarak gördüler.
EPLKleijntjens

3
Ben de buna kefil olabilirim. Null yapılabilir bir alan için bile varsayılan bir değere ihtiyacınız varsa, bunu önce varsayılan bir değerle null yapılamaz olarak değiştirin ve ardından null yapılabilir olarak değiştirin. Bir çocuk sınıfına
sıfırlanamaz

1
Açıklamada nokta. AlterColumn () yalnızca sütun tanımını değiştirir. Mevcut kayıtları hiçbir şekilde etkilemez
Korayem

10
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
Um ... teşekkürler, ama bunun @ web geliştiricisinin cevabından farkı nedir?
Andriy Drozdyuk

1
varsayılan değer parametresini nereye eklemeniz gerektiğini size
söylemiyor

1
@Pushpendra, geliştiricilerin bir zamanlar pek bir şey bilmediklerini unutmaları komik. Her seviyeyi karşılayan ayrıntılı cevapları severim. Harika iş!
usefulBee

5

Bu seçeneğin her zaman etrafta olup olmadığından emin değilim, ancak benzer bir sorunla karşılaştım, aşağıdakileri kullanarak herhangi bir manuel güncelleme çalıştırmadan varsayılan değeri ayarlayabildiğimi gördüm

defaultValueSql: "'NY'"

Sağlanan değer olduğunda bir hata aldım, "NY"daha sonra "GETDATE()"denediğim gibi bir SQL değeri beklediklerini fark ettim "'NY'"ve hile yaptı

tüm çizgi böyle görünüyor

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

Bu cevap sayesinde beni doğru yolda tuttum


3

EF Core 2.1'den beri MigrationBuilder.UpdateData, sütunu değiştirmeden önce değerleri değiştirmek için kullanabilirsiniz (ham SQL kullanmaktan daha temiz):

protected override void Up(MigrationBuilder migrationBuilder)
{
    // Change existing NULL values to NOT NULL values
    migrationBuilder.UpdateData(
        table: tableName,
        column: columnName,
        value: valueInsteadOfNull,
        keyColumn: columnName,
        keyValue: null);

    // Change column type to NOT NULL
    migrationBuilder.AlterColumn<ColumnType>(
        table: tableName,
        name: columnName,
        nullable: false,
        oldClrType: typeof(ColumnType),
        oldNullable: true);
}

2

İşi bitirmek için varlık özelliğinde sadece Auto-Property Initializer'ı kullanmanın yeterli olduğunu buldum.

Örneğin:

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

2
Bu iyi bir cevap (bana yardımcı oldu), ancak bu, veritabanına varsayılan bir değer eklemiyor, koddaki değeri belirliyor.
chris31389

doğru, geçiş değişikliklerinden sonra veritabanına varsayılan değer eklemedi
Chetan Chaudhari

2

Diğer yanıtların çoğu, bu sorunlar ortaya çıktığında manuel olarak nasıl müdahale edileceğine odaklanır.

Taşıma oluşturulduktan sonra, geçişte aşağıdaki değişikliklerden birini gerçekleştirin:

  1. Sütun tanımını bir defaultValue veya defaultSql ifadesini içerecek şekilde değiştirin:
    AlterColumn("dbo.Movies", "Director", c => c.String(nullable: false, default: ""));

  2. AlterColumn'dan önce mevcut sütunları önceden doldurmak için bir SQL ifadesi enjekte edin:
    Sql("UPDATE dbo.Movies SET Director = '' WHERE Director IS NULL");

Bir geçiş betiğine uygulanan manuel değişikliklerin, geçişi yeniden iskeletlendirirseniz üzerine yazılacağını unutmayın. İlk çözüm için, geçiş üretiminin bir parçası olarak bir alanda otomatik olarak varsayılan bir değer tanımlamak için EF'yi genişletmek oldukça kolaydır.

NOT: EF bunu sizin için otomatik olarak yapmaz çünkü varsayılan değer uygulaması her RDBMS sağlayıcısı için farklı olacaktır, ancak aynı zamanda varsayılan değerlerin saf bir EF çalışma zamanında daha az anlamı olduğu için her satır ekleme her özellik için geçerli değeri sağlayacaktır boş olsa bile, varsayılan değer kısıtlaması hiçbir zaman değerlendirilmez.
Bu AlterColumn ifadesi, varsayılan kısıtlamanın devreye girdiği tek zamandır, sanırım bu, SQL Server Geçiş Uygulamasını tasarlayan ekip için daha düşük bir öncelik haline geliyor.

Aşağıdaki çözüm, meta verilerden özel bir Geçiş kodu oluşturucusuna geçmek için öznitelik gösterimini, model yapılandırma kurallarını ve sütun açıklamalarını birleştirir. Öznitelik gösterimini kullanmıyorsanız, 1. ve 2. adımlar, etkilenen her alan için akıcı gösterimle değiştirilebilir.
Burada oyunda birçok teknik var, bir kısmını veya tamamını kullanmaktan çekinmeyin, umarım buradaki herkes için bir değer vardır


  1. Varsayılan Değeri Bildirin Kullanılacak
    varsayılan değeri tanımlamak için mevcut bir özniteliği oluşturun veya yeniden amaçlayın; bu örnekte, kullanım sezgisel olduğundan ve mevcut olma ihtimali olduğundan, ComponentModel.DefaultValueAttribute'tan devralan DefaultValue adlı yeni bir öznitelik oluşturacağız. kod tabanları bu özniteliği zaten uygulamaktadır. Bu uygulamayla, yalnızca tarihler ve diğer özel senaryolar için yararlı olan DefaultValueSql'e erişmek için bu belirli özniteliği kullanmanız gerekir.

    Uygulama

    [DefaultValue("Insert DefaultValue Here")]
    [Required]     /// <--- NEW
    public string Director { get; set; }
    
    // Example of default value sql
    [DefaultValue(DefaultValueSql: "GetDate()")]
    [Required]
    public string LastModified { get; set; }
    

    Öznitelik Tanımı

    namespace EFExtensions
    {
        /// <summary>
        /// Specifies the default value for a property but allows a custom SQL statement to be provided as well. <see cref="MiniTuber.Database.Conventions.DefaultValueConvention"/>
        /// </summary>
        public class DefaultValueAttribute : System.ComponentModel.DefaultValueAttribute
        {
            /// <summary>
            /// Specifies the default value for a property but allows a custom SQL statement to be provided as well. <see cref="MiniTuber.Database.Conventions.DefaultValueConvention"/>
            /// </summary>
            public DefaultValueAttribute() : base("")
            {
            }
    
            /// <i
            /// <summary>
            /// Optional SQL to use to specify the default value.
            /// </summary>
            public string DefaultSql { get; set; }
    
            /// <summary>
            /// Initializes a new instance of the System.ComponentModel.DefaultValueAttribute
            /// class using a Unicode character.
            /// </summary>
            /// <param name="value">
            /// A Unicode character that is the default value.
            /// </param>
            public DefaultValueAttribute(char value) : base(value) { }
    
            /// <summary>
            /// Initializes a new instance of the System.ComponentModel.DefaultValueAttribute
            /// class using an 8-bit unsigned integer.
            /// </summary>
            /// <param name="value">
            /// An 8-bit unsigned integer that is the default value.
            /// </param>
            public DefaultValueAttribute(byte value) : base(value) { }
    
            /// <summary>
            /// Initializes a new instance of the System.ComponentModel.DefaultValueAttribute
            /// class using a 16-bit signed integer.
            /// </summary>
            /// <param name="value">
            /// A 16-bit signed integer that is the default value.
            /// </param>
            public DefaultValueAttribute(short value) : base(value) { }
    
            /// <summary>
            /// Initializes a new instance of the System.ComponentModel.DefaultValueAttribute
            /// class using a 32-bit signed integer.
            /// </summary>
            /// <param name="value">
            /// A 32-bit signed integer that is the default value.
            /// </param>
            public DefaultValueAttribute(int value) : base(value) { }
    
            /// <summary>
            /// Initializes a new instance of the System.ComponentModel.DefaultValueAttribute
            /// class using a 64-bit signed integer.
            /// </summary>
            /// <param name="value">
            /// A 64-bit signed integer that is the default value.
            /// </param>
            public DefaultValueAttribute(long value) : base(value) { }
    
            /// <summary>
            /// Initializes a new instance of the System.ComponentModel.DefaultValueAttribute
            /// class using a single-precision floating point number.
            /// </summary>
            /// <param name="value">
            /// A single-precision floating point number that is the default value.
            /// </param>
            public DefaultValueAttribute(float value) : base(value) { }
    
            /// <summary>
            /// Initializes a new instance of the System.ComponentModel.DefaultValueAttribute
            /// class using a double-precision floating point number.
            /// </summary>
            /// <param name="value">
            /// A double-precision floating point number that is the default value.
            /// </param>
            public DefaultValueAttribute(double value) : base(value) { }
    
            /// <summary>
            /// Initializes a new instance of the System.ComponentModel.DefaultValueAttribute
            /// class using a System.Boolean value.
            /// </summary>
            /// <param name="value">
            /// A System.Boolean that is the default value.
            /// </param>
            public DefaultValueAttribute(bool value) : base(value) { }
    
            /// <summary>
            /// Initializes a new instance of the System.ComponentModel.DefaultValueAttribute
            /// class using a System.String.
            /// </summary>
            /// <param name="value">
            /// A System.String that is the default value.
            /// </param>
            public DefaultValueAttribute(string value) : base(value) { }
    
            /// <summary>
            /// Initializes a new instance of the System.ComponentModel.DefaultValueAttribute
            /// class.
            /// </summary>
            /// <param name="value">
            /// An System.Object that represents the default value.
            /// </param>
            public DefaultValueAttribute(object value) : base(value) { }
    
            /// /// <inheritdoc/>
            /// Initializes a new instance of the System.ComponentModel.DefaultValueAttribute
            /// class, converting the specified value to the specified type, and using an invariant
            /// culture as the translation context.
            /// </summary>
            /// <param name="type">
            /// A System.Type that represents the type to convert the value to.
            /// </param>
            /// <param name="value">
            /// A System.String that can be converted to the type using the System.ComponentModel.TypeConverter
            /// for the type and the U.S. English culture.
            /// </param>
            public DefaultValueAttribute(Type type, string value) : base(value) { }
        }
    }
    
  2. Varsayılan değeri sütun açıklamalarına enjekte etmek için bir kural oluşturma
    Sütun açıklamaları, sütunlar hakkındaki özel meta verileri geçiş komut dosyası oluşturucusuna geçirmek için kullanılır.
    Bunu yapmak için bir kural kullanmak, her alan için ayrı ayrı belirtmek yerine, birçok özellik için meta verilerin ne kadar akıcı bir şekilde tanımlanıp değiştirilebileceğini basitleştirmek için Öznitelik gösteriminin arkasındaki gücü gösterir.

    namespace EFExtensions
    {
    
        /// <summary>
        /// Implement SQL Default Values from System.ComponentModel.DefaultValueAttribute
        /// </summary>
        public class DefaultValueConvention : Convention
        {
            /// <summary>
            /// Annotation Key to use for Default Values specified directly as an object
            /// </summary>
            public const string DirectValueAnnotationKey = "DefaultValue";
            /// <summary>
            /// Annotation Key to use for Default Values specified as SQL Strings
            /// </summary>
            public const string SqlValueAnnotationKey = "DefaultSql";
    
            /// <summary>
            /// Implement SQL Default Values from System.ComponentModel.DefaultValueAttribute
            /// </summary>
            public DefaultValueConvention()
            {
                // Implement SO Default Value Attributes first
                this.Properties()
                        .Where(x => x.HasAttribute<EFExtensions.DefaultValueAttribute>())
                        .Configure(c => c.HasColumnAnnotation(
                            c.GetAttribute<EFExtensions.DefaultValueAttribute>().GetDefaultValueAttributeKey(),
                            c.GetAttribute<EFExtensions.DefaultValueAttribute>().GetDefaultValueAttributeValue()
                            ));
    
                // Implement Component Model Default Value Attributes, but only if it is not the SO implementation
                this.Properties()
                        .Where(x => x.HasAttribute<System.ComponentModel.DefaultValueAttribute>())
                        .Where(x => !x.HasAttribute<MiniTuber.DataAnnotations.DefaultValueAttribute>())
                        .Configure(c => c.HasColumnAnnotation(
                            DefaultValueConvention.DirectValueAnnotationKey, 
                            c.GetAttribute<System.ComponentModel.DefaultValueAttribute>().Value
                            ));
            }
        }
    
        /// <summary>
        /// Extension Methods to simplify the logic for building column annotations for Default Value processing
        /// </summary>
        public static partial class PropertyInfoAttributeExtensions
        {
            /// <summary>
            /// Wrapper to simplify the lookup for a specific attribute on a property info.
            /// </summary>
            /// <typeparam name="T">Type of attribute to lookup</typeparam>
            /// <param name="self">PropertyInfo to inspect</param>
            /// <returns>True if an attribute of the requested type exists</returns>
            public static bool HasAttribute<T>(this PropertyInfo self) where T : Attribute
            {
                return self.GetCustomAttributes(false).OfType<T>().Any();
            }
    
            /// <summary>
            /// Wrapper to return the first attribute of the specified type
            /// </summary>
            /// <typeparam name="T">Type of attribute to return</typeparam>
            /// <param name="self">PropertyInfo to inspect</param>
            /// <returns>First attribuite that matches the requested type</returns>
            public static T GetAttribute<T>(this System.Data.Entity.ModelConfiguration.Configuration.ConventionPrimitivePropertyConfiguration self) where T : Attribute
            {
                return self.ClrPropertyInfo.GetCustomAttributes(false).OfType<T>().First();
            }
    
            /// <summary>
            /// Helper to select the correct DefaultValue annotation key based on the attribute values
            /// </summary>
            /// <param name="self"></param>
            /// <returns></returns>
            public static string GetDefaultValueAttributeKey(this EFExtensions.DefaultValueAttribute self)
            {
                return String.IsNullOrWhiteSpace(self.DefaultSql) ? DefaultValueConvention.DirectValueAnnotationKey : DefaultValueConvention.SqlValueAnnotationKey;
            }
    
            /// <summary>
            /// Helper to select the correct attribute property to send as a DefaultValue annotation value
            /// </summary>
            /// <param name="self"></param>
            /// <returns></returns>
            public static object GetDefaultValueAttributeValue(this EFExtensions.DefaultValueAttribute self)
            {
                return String.IsNullOrWhiteSpace(self.DefaultSql) ? self.Value : self.DefaultSql;
            }
        }
    
    }
    
  3. Konvansiyonu DbContext'e Ekleme
    Bunu elde etmenin birçok yolu vardır, kuralları ModelCreation mantığımdaki ilk özel adım olarak ilan etmeyi seviyorum, bu DbContext sınıfınızda olacaktır.

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        // Use our new DefaultValueConvention
        modelBuilder.Conventions.Add<EFExtensions.DefaultValueConvention>();
    
        // My personal favourites ;)
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
    
    }
    
  4. MigrationCodeGenerator'ü Geçersiz Kıl
    Bu ek açıklamalar model içindeki sütun tanımlarına uygulandığına göre, bu ek açıklamaları kullanmak için geçiş komut dosyası oluşturucusunu değiştirmemiz gerekiyor. Bunun için, System.Data.Entity.Migrations.Design.CSharpMigrationCodeGeneratoryalnızca minimum miktarda değişiklik enjekte etmemiz gerektiğinden miras alacağız.
    Özel açıklamamızı işledikten sonra, son çıktıya serileştirilmesini önlemek için sütun tanımından kaldırmamız gerekir.

    Diğer kullanımları keşfetmek için temel sınıf koduna bakın: http://entityframework.codeplex.com/sourcecontrol/latest#src/EntityFramework/Migrations/Design/CSharpMigrationCodeGenerator.cs

    namespace EFExtensions
    {
        /// <summary>
        /// Implement DefaultValue constraint definition in Migration Scripts.
        /// </summary>
        /// <remarks>
        /// Original guide that provided inspiration for this https://romiller.com/2012/11/30/code-first-migrations-customizing-scaffolded-code/
        /// </remarks>
        public class CustomCodeGenerator : System.Data.Entity.Migrations.Design.CSharpMigrationCodeGenerator
        {
            /// <summary>
            /// Inject Default values from the DefaultValue attribute, if the DefaultValueConvention has been enabled.
            /// </summary>
            /// <seealso cref="DefaultValueConvention"/>
            /// <param name="column"></param>
            /// <param name="writer"></param>
            /// <param name="emitName"></param>
            protected override void Generate(ColumnModel column, IndentedTextWriter writer, bool emitName = false)
            {
                var annotations = column.Annotations?.ToList();
                if (annotations != null && annotations.Any())
                {
                    for (int index = 0; index < annotations.Count; index ++)
                    {
                        var annotation = annotations[index];
                        bool handled = true;
    
                        try
                        {
                            switch (annotation.Key)
                            {
                                case DefaultValueConvention.SqlValueAnnotationKey:
                                    if (annotation.Value?.NewValue != null)
                                    {
                                        column.DefaultValueSql = $"{annotation.Value.NewValue}";
                                    }
                                    break;
                                case DefaultValueConvention.DirectValueAnnotationKey:
                                    if (annotation.Value?.NewValue != null)
                                    {
                                        column.DefaultValue = Convert.ChangeType(annotation.Value.NewValue, column.ClrType);
                                    }
                                    break;
                                default:
                                    handled = false;
                                    break;
                            }
                        }
                        catch(Exception ex)
                        {
                            // re-throw with specific debug information
                            throw new ApplicationException($"Failed to Implement Column Annotation for column: {column.Name} with key: {annotation.Key} and new value: {annotation.Value.NewValue}", ex);
                        }
    
                        if(handled)
                        {
                            // remove the annotation, it has been applied
                            column.Annotations.Remove(annotation.Key);
                        }
                    }
                }
                base.Generate(column, writer, emitName);
            }
    
            /// <summary>
            /// Generates class summary comments and default attributes
            /// </summary>
            /// <param name="writer"> Text writer to add the generated code to. </param>
            /// <param name="designer"> A value indicating if this class is being generated for a code-behind file. </param>
            protected override void WriteClassAttributes(IndentedTextWriter writer, bool designer)
            {
                writer.WriteLine("/// <summary>");
                writer.WriteLine("/// Definition of the Migration: {0}", this.ClassName);
                writer.WriteLine("/// </summary>");
                writer.WriteLine("/// <remarks>");
                writer.WriteLine("/// Generated Time: {0}", DateTime.Now);
                writer.WriteLine("/// Generated By: {0}", Environment.UserName);
                writer.WriteLine("/// </remarks>");
                base.WriteClassAttributes(writer, designer);
            }
    
    
        }
    }
    
  5. CustomCodeGenerator'ı
    kaydedin Son adım, DbMigration Configuration dosyasında, kullanılacak Code Generator'ı belirtmemiz gerekiyor, varsayılan olarak Migration klasörünüzdeki Configuration.cs dosyasını arayın ...

    internal sealed class Configuration : DbMigrationsConfiguration<YourApplication.Database.Context>
    {
        public Configuration()
        {
            // I recommend that auto-migrations be disabled so that we control
            // the migrations explicitly 
            AutomaticMigrationsEnabled = false;
            CodeGenerator = new EFExtensions.CustomCodeGenerator();
        }
    
        protected override void Seed(YourApplication.Database.Context context)
        {
            //   Your custom seed logic here
        }
    }
    

0

Bazı nedenlerden dolayı, kendime açıklayamadığım için onaylanan cevap artık benim için işe yaramıyor.

Başka bir uygulamada çalıştı, çalıştığım uygulamada çalışmıyor.

Bu nedenle, alternatif, ancak oldukça verimsiz bir çözüm, aşağıda gösterildiği gibi SaveChanges () Yöntemini geçersiz kılmak olacaktır. Bu yöntem Context sınıfında olmalıdır.

    public override int SaveChanges()
    {
        foreach (var entry in ChangeTracker.Entries().Where(entry => entry.Entity.GetType().GetProperty("ColumnName") != null))
        {
            if (entry.State == EntityState.Added)
            {
                entry.Property("ColumnName").CurrentValue = "DefaultValue";
            }
        }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.