Entity Framework 6 Code ก่อนค่าเริ่มต้น


203

จะมีวิธี "ฉลาด" เพื่อให้ค่าเริ่มต้นคุณสมบัติเฉพาะ?

บางทีโดย DataAnnotations สิ่งที่ชอบ:

[DefaultValue("true")]
public bool Active { get; set; }

ขอบคุณ.


อาจลองในตัวสร้างthis.Active = true;? ฉันคิดว่าค่า DB จะมีความสำคัญเมื่อดึงข้อมูล แต่ระวังถ้ามีสิ่งใหม่แล้วแนบเอนทิตีสำหรับการอัปเดตโดยไม่ดึงข้อมูลมาก่อนเนื่องจากการติดตามการเปลี่ยนแปลงอาจเห็นสิ่งนี้ตามที่คุณต้องการอัปเดตค่า ความคิดเห็นเพราะฉันไม่ได้ใช้ EF มานานและฉันรู้สึกว่านี่เป็นการถ่ายภาพในที่มืด
AaronLS

3
ขอบคุณสำหรับการตอบกลับฉันใช้วิธีนี้จนถึงตอนนี้stackoverflow.com/a/5032578/2913441แต่ฉันคิดว่าอาจจะมีวิธีที่ดีกว่า
marino-krk

2
public bool Inactive { get; set; }😉
Jesse Hufstetler

ดังที่เอกสารของ Microsoft บอกว่า "คุณไม่สามารถตั้งค่าเริ่มต้นโดยใช้คำอธิบายประกอบข้อมูล"
hmfarimani

คำตอบ:


166

คุณสามารถทำได้โดยแก้ไขรหัสการโยกย้ายครั้งแรก:

public override void Up()
{    
   AddColumn("dbo.Events", "Active", c => c.Boolean(nullable: false, defaultValue: true));
} 

6
ฉันไม่แน่ใจว่านี้จะทำงานถ้า OP ไม่ได้กำหนดมาเป็นพิเศษActiveเพื่อให้trueเมื่อสร้างEventวัตถุเช่นกัน ค่าเริ่มต้นจะfalseอยู่ในคุณสมบัติบูลที่ไม่สามารถลบล้างได้เสมอดังนั้นหากไม่มีการเปลี่ยนแปลงนี่คือสิ่งที่เฟรมเวิร์กเอนทิตีจะบันทึกลงในฐานข้อมูล หรือฉันกำลังพลาดอะไรอยู่?
GFoley83

6
@ GFoley83 ใช่คุณพูดถูก วิธีนี้เพิ่มข้อ จำกัด เริ่มต้นที่ระดับฐานข้อมูลเท่านั้น สำหรับโซลูชันที่สมบูรณ์คุณยังต้องกำหนดค่าเริ่มต้นในตัวสร้างเอนทิตีหรือใช้คุณสมบัติที่มีเขตข้อมูลสำรองตามที่แสดงในคำตอบข้างต้น
gdbdable

1
ใช้งานได้กับประเภทฐาน สำหรับสิ่งที่ต้องการ DATETIMEOFFSET ให้ใช้, defaultValueSql: "SYSDATETIMEOFFSET" และไม่ใช่ defaultValue เป็นค่าเริ่มต้นนี้: System.DateTimeOffset ตอนนี้จะแก้ไขสตริงของค่าปัจจุบันของระบบและเวลาที่ตั้งไว้
OzBob

3
AFAIK การเปลี่ยนแปลงที่ทำด้วยมือของคุณจะหายไปในกรณีของการย้ายฐานการอพยพอีกครั้ง
Alexander Powolozki

1
@ninbit ฉันคิดว่าคุณควรจะย้ายการเขียนเพื่อลบมันในระดับฐานข้อมูลก่อนจากนั้นเปลี่ยนการแมป DAL ของคุณ
gdbdable

74

ไม่นานมานี้ แต่ได้ทิ้งโน้ตให้คนอื่น ฉันบรรลุสิ่งที่ต้องการด้วยแอตทริบิวต์และฉันตกแต่งฟิลด์คลาสโมเดลของฉันด้วยแอตทริบิวต์นั้นตามที่ต้องการ

[SqlDefaultValue(DefaultValue = "getutcdate()")]
public DateTime CreatedDateUtc { get; set; }

รับความช่วยเหลือจาก 2 บทความเหล่านี้:

ฉันทำอะไรลงไป:

กำหนดคุณสมบัติ

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class SqlDefaultValueAttribute : Attribute
{
    public string DefaultValue { get; set; }
}

ใน "OnModelCreating" ของบริบท

modelBuilder.Conventions.Add( new AttributeToColumnAnnotationConvention<SqlDefaultValueAttribute, string>("SqlDefaultValue", (p, attributes) => attributes.Single().DefaultValue));

ใน SqlGenerator ที่กำหนดเอง

private void SetAnnotatedColumn(ColumnModel col)
{
    AnnotationValues values;
    if (col.Annotations.TryGetValue("SqlDefaultValue", out values))
    {
         col.DefaultValueSql = (string)values.NewValue;
    }
}

จากนั้นในคอนสตรัคเตอร์ Migration Configuration ให้ลงทะเบียนตัวสร้าง SQL แบบกำหนดเอง

SetSqlGenerator("System.Data.SqlClient", new CustomMigrationSqlGenerator());

6
คุณสามารถทำได้ทั่วโลกโดยไม่ต้องใส่[SqlDefaultValue(DefaultValue = "getutcdate()")]ทุกเอนทิตี 1) เพียงลบmodelBuilder.Conventions.Add( new AttributeToColumnAnnotationConvention<SqlDefaultValueAttribute, string>("SqlDefaultValue", (p, attributes) => attributes.Single().DefaultValue)); 2) เพิ่มmodelBuilder.Properties().Where(x => x.PropertyType == typeof(DateTime)).Configure(c => c.HasColumnType("datetime2").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed).HasColumnAnnotation("SqlDefaultValue", "getdate()"));
Daniel Skowroński

1
SqlGenerator ที่กำหนดเองอยู่ที่ไหนโปรด?
ᴍᴀᴛᴛʙᴀᴋᴇʀ

3
SqlGenerator ที่กำหนดเองมาจากที่นี่: andy.mehalick.com/2014/02/06/…
ravinsp

1
@ravinsp เหตุใดจึงไม่ปรับแต่งคลาส MigrationCodeGenerator เพื่อให้มีการย้ายข้อมูลที่ถูกต้องมากกว่ารหัส SqlGenerator รหัส SQL เป็นขั้นตอนสุดท้าย ...
Alex

@ Alex พยายาม! สิ่งนี้จะใช้ได้ดีกว่าการฉีดรหัส SQL แต่ฉันไม่แน่ใจเกี่ยวกับความซับซ้อนของการแทนที่ C # MigrationCodeGenerator
ravinsp

73

คำตอบข้างต้นช่วยได้จริงๆ แต่ให้ส่วนหนึ่งของการแก้ปัญหาเท่านั้น ปัญหาหลักคือทันทีที่คุณลบแอตทริบิวต์ค่าเริ่มต้นข้อ จำกัด ในคอลัมน์ในฐานข้อมูลจะไม่ถูกลบ ดังนั้นค่าเริ่มต้นก่อนหน้านี้จะยังคงอยู่ในฐานข้อมูล

นี่เป็นวิธีการแก้ปัญหาอย่างเต็มรูปแบบรวมถึงการลบข้อ จำกัด ของ SQL ในการลบแอตทริบิวต์ ฉันกำลังใช้DefaultValueแอตทริบิวต์ดั้งเดิมของ. NET Framework อีกครั้ง

การใช้

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[DefaultValue("getutcdate()")]
public DateTime CreatedOn { get; set; }

เพื่อให้ทำงานได้คุณจะต้องอัปเดตไฟล์IdentityModels.csและConfiguration.cs

ไฟล์ IdentityModels.cs

เพิ่ม / อัปเดตวิธีนี้ในApplicationDbContextชั้นเรียนของคุณ

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
            base.OnModelCreating(modelBuilder);
            var convention = new AttributeToColumnAnnotationConvention<DefaultValueAttribute, string>("SqlDefaultValue", (p, attributes) => attributes.SingleOrDefault().Value.ToString());
            modelBuilder.Conventions.Add(convention);
}

ไฟล์ Configuration.cs

อัปเดตตัวConfigurationสร้างคลาสของคุณโดยการลงทะเบียนเครื่องมือสร้าง SQL แบบกำหนดเองเช่นนี้:

internal sealed class Configuration : DbMigrationsConfiguration<ApplicationDbContext>
{
    public Configuration()
    {
        // DefaultValue Sql Generator
        SetSqlGenerator("System.Data.SqlClient", new DefaultValueSqlServerMigrationSqlGenerator());
    }
}

จากนั้นเพิ่มคลาสตัวสร้าง Sql ที่กำหนดเอง (คุณสามารถเพิ่มลงในไฟล์Configuration.csหรือไฟล์แยกต่างหาก)

internal class DefaultValueSqlServerMigrationSqlGenerator : SqlServerMigrationSqlGenerator
{
    private int dropConstraintCount = 0;

    protected override void Generate(AddColumnOperation addColumnOperation)
    {
        SetAnnotatedColumn(addColumnOperation.Column, addColumnOperation.Table);
        base.Generate(addColumnOperation);
    }

    protected override void Generate(AlterColumnOperation alterColumnOperation)
    {
        SetAnnotatedColumn(alterColumnOperation.Column, alterColumnOperation.Table);
        base.Generate(alterColumnOperation);
    }

    protected override void Generate(CreateTableOperation createTableOperation)
    {
        SetAnnotatedColumns(createTableOperation.Columns, createTableOperation.Name);
        base.Generate(createTableOperation);
    }

    protected override void Generate(AlterTableOperation alterTableOperation)
    {
        SetAnnotatedColumns(alterTableOperation.Columns, alterTableOperation.Name);
        base.Generate(alterTableOperation);
    }

    private void SetAnnotatedColumn(ColumnModel column, string tableName)
    {
        AnnotationValues values;
        if (column.Annotations.TryGetValue("SqlDefaultValue", out values))
        {
            if (values.NewValue == null)
            {
                column.DefaultValueSql = null;
                using (var writer = Writer())
                {
                    // Drop Constraint
                    writer.WriteLine(GetSqlDropConstraintQuery(tableName, column.Name));
                    Statement(writer);
                }
            }
            else
            {
                column.DefaultValueSql = (string)values.NewValue;
            }
        }
    }

    private void SetAnnotatedColumns(IEnumerable<ColumnModel> columns, string tableName)
    {
        foreach (var column in columns)
        {
            SetAnnotatedColumn(column, tableName);
        }
    }

    private string GetSqlDropConstraintQuery(string tableName, string columnName)
    {
        var tableNameSplittedByDot = tableName.Split('.');
        var tableSchema = tableNameSplittedByDot[0];
        var tablePureName = tableNameSplittedByDot[1];

        var str = $@"DECLARE @var{dropConstraintCount} nvarchar(128)
SELECT @var{dropConstraintCount} = name
FROM sys.default_constraints
WHERE parent_object_id = object_id(N'{tableSchema}.[{tablePureName}]')
AND col_name(parent_object_id, parent_column_id) = '{columnName}';
IF @var{dropConstraintCount} IS NOT NULL
    EXECUTE('ALTER TABLE {tableSchema}.[{tablePureName}] DROP CONSTRAINT [' + @var{dropConstraintCount} + ']')";

        dropConstraintCount = dropConstraintCount + 1;
        return str;
    }
}

2
วิธีนี้ใช้ได้ผลดีสำหรับฉัน การปรับปรุงอย่างหนึ่งที่ฉันทำคือการแทนที่ Generate (CreateTableOperation createTableOperation) และ Generate (AddColumnOperation addColumnOperation) ด้วยตรรกะเดียวกันเพื่อให้สถานการณ์เหล่านั้นถูกจับเช่นกัน ฉันตรวจสอบเฉพาะค่า NewValue เป็นโมฆะเพราะฉันต้องการให้ค่าเริ่มต้นเป็นสตริงว่าง
Delorian

2
@Delorian ฉันได้อัปเดตคำตอบของฉันแล้วขอบคุณสำหรับความคิดเห็นของคุณ
Jevgenij Martynenko

1
ฉันได้ทำการแก้ไขโพสต์ของคุณเพื่อสนับสนุนอินสแตนซ์ที่การย้อนกลับลดลงมากกว่าหนึ่งข้อ จำกัด สคริปต์ของคุณจะมีข้อผิดพลาดที่ระบุว่า @con ได้รับการประกาศแล้ว ฉันสร้างตัวแปรส่วนตัวเพื่อเก็บตัวนับและเพิ่มมันแบบง่ายๆ ฉันยังเปลี่ยนรูปแบบของข้อ จำกัด การปล่อยให้ใกล้เคียงกับสิ่งที่ EF ส่งไปยัง SQL มากขึ้นเมื่อสร้างข้อ จำกัด เยี่ยมมากในเรื่องนี้!
แบรด

1
ขอบคุณสำหรับวิธีแก้ปัญหา แต่ฉันมีสองปัญหา: 1. ชื่อตารางต้องใช้วงเล็บ 2. ในการอัพเดทค่าใหม่ไม่ได้ตั้งค่าและตั้งค่าเริ่มต้นแทน!
Omid-RH

1
ฉันต้องตั้งค่า[DatabaseGenerated(DatabaseGeneratedOption.Computed)]คุณลักษณะหรือไม่ ถ้าเป็นเช่นนั้นทำไม ในการทดสอบของฉันดูเหมือนว่าจะไม่มีผลกระทบออกไป
RamNow

26

คุณสมบัติโมเดลของคุณไม่จำเป็นต้องเป็น 'คุณสมบัติอัตโนมัติ' แม้ว่าจะง่ายกว่าก็ตาม และแอตทริบิวต์ DefaultValue เป็นเพียงข้อมูลเมตาดาต้าที่ได้รับคำตอบที่นี่เป็นอีกทางเลือกหนึ่งสำหรับวิธีการสร้าง

public class Track
{

    private const int DEFAULT_LENGTH = 400;
    private int _length = DEFAULT_LENGTH;
    [DefaultValue(DEFAULT_LENGTH)]
    public int LengthInMeters {
        get { return _length; }
        set { _length = value; }
    }
}

เมื่อเทียบกับ

public class Track
{
    public Track()
    {
        LengthInMeters = 400;   
    }

    public int LengthInMeters { get; set; }        
}

สิ่งนี้จะทำงานสำหรับแอปพลิเคชันที่สร้างและใช้ข้อมูลโดยใช้คลาสเฉพาะนี้เท่านั้น โดยทั่วไปแล้วนี่ไม่ใช่ปัญหาหากรหัสการเข้าถึงข้อมูลเป็นแบบรวมศูนย์ หากต้องการอัปเดตค่าในแอปพลิเคชันทั้งหมดคุณต้องกำหนดค่าแหล่งข้อมูลเพื่อตั้งค่าเริ่มต้น คำตอบของ Deviแสดงให้เห็นว่าสามารถทำได้อย่างไรโดยใช้การย้ายข้อมูล, sql หรือภาษาใดก็ตามที่แหล่งข้อมูลของคุณพูด


21
หมายเหตุ: นี่จะไม่ได้ตั้งค่าเริ่มต้นในฐานข้อมูล โปรแกรมอื่น ๆ ที่ไม่ได้ใช้เอนทิตีของคุณจะไม่ได้รับค่าเริ่มต้นนั้น
Eric J.

ส่วนนี้ของคำตอบ แต่มันไม่ทำงานถ้าคุณกำลังแทรกเร็กคอร์ดในวิธีอื่นนอกเหนือจาก Entity Framework นอกจากนี้หากคุณกำลังสร้างคอลัมน์ที่ไม่เป็น null ใหม่ในตารางสิ่งนี้จะไม่ให้ความสามารถในการตั้งค่าเริ่มต้นสำหรับระเบียนที่มีอยู่ @devi มีส่วนเพิ่มเติมที่มีประโยชน์ด้านล่าง
d512

ทำไมวิธีแรกของคุณถึงวิธี "ถูกต้อง"? คุณจะพบกับปัญหาที่ไม่ได้ตั้งใจด้วยวิธีการสร้างหรือไม่?
WiteCastle

เรื่องของความคิดเห็นและการเปลี่ยนแปลงเหล่านั้น :) และอาจจะไม่
calebboyd

2
ภายใต้สถานการณ์บางอย่างฉันมีปัญหากับวิธีการกำหนด การตั้งค่าเริ่มต้นในเขตข้อมูลสำรองดูเหมือนจะเป็นวิธีการแก้ปัญหาที่รุกรานน้อยที่สุด
Lucent Fox

11

สิ่งที่ฉันทำฉันเริ่มต้นค่าในตัวสร้างของเอนทิตี

หมายเหตุ: แอตทริบิวต์ค่าเริ่มต้นจะไม่ตั้งค่าคุณสมบัติของคุณโดยอัตโนมัติคุณต้องทำด้วยตัวเอง


4
ปัญหาเกี่ยวกับการกำหนดค่าคอนสตรัคเตอร์คือ EF จะทำการอัพเดทฐานข้อมูลเมื่อทำธุรกรรม
Luka

แบบจำลองแรกสร้างค่าเริ่มต้นด้วยวิธีนี้
ลูคัส

DefaultValue เป็นเผ่าพันธุ์ที่อาศัยอยู่ในดินแดนที่ห่างไกลและอายเกินกว่าที่จะเผชิญหน้ากับคุณสมบัติของคุณได้ อย่าทำให้เสียงมันกลัวได้ง่าย - ถ้ามันเข้ามาใกล้พอที่จะได้ยินมัน +1 สำหรับการระบุไม่ชัดเจนเลย
Risadinha

8

หลังจากความคิดเห็น @SedatKapanoglu ฉันกำลังเพิ่มวิธีการทั้งหมดที่ใช้งานได้เพราะเขาพูดถูกเพียงใช้ API ได้อย่างคล่องแคล่วไม่ทำงาน

1- สร้างตัวสร้างโค้ดที่กำหนดเองและแทนที่สร้างสำหรับ ColumnModel

   public class ExtendedMigrationCodeGenerator : CSharpMigrationCodeGenerator
{

    protected override void Generate(ColumnModel column, IndentedTextWriter writer, bool emitName = false)
    {

        if (column.Annotations.Keys.Contains("Default"))
        {
            var value = Convert.ChangeType(column.Annotations["Default"].NewValue, column.ClrDefaultValue.GetType());
            column.DefaultValue = value;
        }


        base.Generate(column, writer, emitName);
    }

}

2- กำหนดตัวสร้างรหัสใหม่:

public sealed class Configuration : DbMigrationsConfiguration<Data.Context.EfSqlDbContext>
{
    public Configuration()
    {
        CodeGenerator = new ExtendedMigrationCodeGenerator();
        AutomaticMigrationsEnabled = false;
    }
}

3- ใช้ API ที่คล่องแคล่วเพื่อสร้างบันทึกย่อ:

public static void Configure(DbModelBuilder builder){    
builder.Entity<Company>().Property(c => c.Status).HasColumnAnnotation("Default", 0);            
}

โปรดดูโซลูชันที่สมบูรณ์ของฉันฉันเพิ่มการใช้งานทั้งหมดของฉันไปแล้วขอบคุณ
Denny Puig

5

มันง่ายมาก! เพียงแค่ใส่คำอธิบายประกอบที่จำเป็น

[Required]
public bool MyField { get; set; }

ผลลัพธ์การโยกย้ายจะเป็น:

migrationBuilder.AddColumn<bool>(
name: "MyField",
table: "MyTable",
nullable: false,
defaultValue: false);

ถ้าคุณต้องการจริงเปลี่ยนค่าเริ่มต้นเป็นจริงในการโยกย้ายก่อนที่จะปรับปรุงฐานข้อมูล


การโยกย้ายที่สร้างอัตโนมัติสามารถเปลี่ยนแปลงได้และคุณจะลืมค่าเริ่มต้น
Fernando Torres

เรียบง่ายและใช้งานได้ช่วยเพิ่มคอลัมน์ในตารางที่มีอยู่อย่างรวดเร็วด้วยข้อ จำกัด foreign key ในคอลัมน์ใหม่ ขอบคุณ
po10cySA

แล้วถ้าเราต้องการค่าเริ่มต้นtrueล่ะ?
Christos Lytras

5

ฉันยอมรับว่าวิธีการของฉันหนีจากแนวคิด "Code First" ทั้งหมด แต่ถ้าคุณมีความสามารถในการเปลี่ยนค่าเริ่มต้นในตารางตัวเอง ... มันง่ายกว่าความยาวที่คุณต้องทำตามข้างต้น ... ฉันขี้เกียจเกินกว่าที่จะทำงานทั้งหมดได้!

ดูเหมือนว่าแนวคิดดั้งเดิมของผู้โพสต์จะใช้งานได้:

[DefaultValue(true)]
public bool IsAdmin { get; set; }

ฉันคิดว่าพวกเขาทำผิดพลาดในการเพิ่มคำพูด ... แต่ก็ไม่ได้หยั่งรู้เช่นนั้น คำแนะนำอื่น ๆ มีมากเกินไปสำหรับฉัน (อนุญาตให้ฉันมีสิทธิ์ที่จำเป็นในการเข้าไปในตารางและทำการเปลี่ยนแปลง ... ซึ่งนักพัฒนาไม่ได้ทุกคนจะได้ในทุกสถานการณ์) ในที่สุดฉันก็ทำแบบเก่า ๆ ฉันตั้งค่าเริ่มต้นในตาราง SQL Server ... ฉันหมายถึงเพียงพอแล้ว! หมายเหตุ: ฉันทดสอบเพิ่มเติมเกี่ยวกับการเพิ่มการย้ายข้อมูลและการอัปเดตฐานข้อมูลและการเปลี่ยนแปลงที่ติดอยู่ ป้อนคำอธิบายรูปภาพที่นี่


1

Just Overload ตัวสร้างปริยายของคลาส Model และส่งผ่านพารามิเตอร์ที่เกี่ยวข้องซึ่งคุณอาจจะหรืออาจจะไม่ใช้ก็ได้ ด้วยวิธีนี้คุณสามารถระบุค่าเริ่มต้นสำหรับแอตทริบิวต์ได้อย่างง่ายดาย ด้านล่างเป็นตัวอย่าง

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Aim.Data.Domain
{
    [MetadataType(typeof(LoginModel))]
    public partial class Login
    {       
        public Login(bool status)
        {
            this.CreatedDate = DateTime.Now;
            this.ModifiedDate = DateTime.Now;
            this.Culture = "EN-US";
            this.IsDefaultPassword = status;
            this.IsActive = status;
            this.LoginLogs = new HashSet<LoginLog>();
            this.LoginLogHistories = new HashSet<LoginLogHistory>();
        }


    }

    public class LoginModel
    {

        [Key]
        [ScaffoldColumn(false)] 
        public int Id { get; set; }
        [Required]
        public string LoginCode { get; set; }
        [Required]
        public string Password { get; set; }
        public string LastPassword { get; set; }     
        public int UserGroupId { get; set; }
        public int FalseAttempt { get; set; }
        public bool IsLocked { get; set; }
        public int CreatedBy { get; set; }       
        public System.DateTime CreatedDate { get; set; }
        public Nullable<int> ModifiedBy { get; set; }      
        public Nullable<System.DateTime> ModifiedDate { get; set; }       
        public string Culture { get; set; }        
        public virtual ICollection<LoginLog> LoginLogs { get; set; }
        public virtual ICollection<LoginLogHistory> LoginLogHistories { get; set; }
    }

}

คำแนะนำนี้เป็นตรรกะฝั่งไคลเอ็นต์ทั้งหมด "ใช้งานได้" ตราบเท่าที่คุณจะโต้ตอบกับฐานข้อมูลโดยใช้แอปพลิเคชันเท่านั้น ทันทีที่มีคนต้องการแทรกระเบียนด้วยตนเองหรือจากแอปพลิเคชันอื่นคุณจะพบข้อเสียว่าไม่มีนิพจน์เริ่มต้นในสคีมาและไม่สามารถปรับขนาดไปยังไคลเอนต์อื่นได้ แม้ว่าจะไม่ได้ระบุไว้อย่างชัดเจนหัวข้อที่ชอบด้วยกฎหมายนี้แสดงถึงความต้องการในการให้ EF สร้างการย้ายข้อมูลที่วางนิพจน์เริ่มต้นไว้ในคำจำกัดความของคอลัมน์
ทอม

0

ให้พิจารณาว่าคุณมีชื่อคลาสที่ชื่อผลิตภัณฑ์และคุณมีฟิลด์ IsActive เพียงคุณต้องสร้างคอนสตรัค:

Public class Products
{
    public Products()
    {
       IsActive = true;
    }
 public string Field1 { get; set; }
 public string Field2 { get; set; }
 public bool IsActive { get; set; }
}

จากนั้นค่าเริ่มต้น IsActive ของคุณจะเป็นจริง!

Edite :

ถ้าคุณต้องการทำสิ่งนี้กับ SQL ให้ใช้คำสั่งนี้:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.IsActive)
        .HasDefaultValueSql("true");
}

เพียงแค่นี้ไม่ใช่คำถาม มันเป็นข้อ จำกัด เกี่ยวกับค่าเริ่มต้นในฐานข้อมูลเอง
Gábor

4
@Hatef การแก้ไขของคุณจะใช้กับ EF Core เท่านั้น คำถามเกี่ยวกับ EF 6
ไมเคิล

3
HasDefaultValueSql นี้ไม่สามารถใช้ได้ใน EF6
tatigo

0

ใน EF core ที่วางจำหน่าย 27 มิถุนายน 2016 คุณสามารถใช้ API ได้อย่างคล่องแคล่วสำหรับการตั้งค่าเริ่มต้น ไปที่คลาส ApplicationDbContext ค้นหา / สร้างชื่อเมธอด OnModelCreating และเพิ่ม API ได้อย่างคล่องแคล่วต่อไปนี้

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<YourTableName>()
        .Property(b => b.Active)
        .HasDefaultValue(true);
}

0

ใน. NET Core 3.1 คุณสามารถทำสิ่งต่อไปนี้ในคลาสโมเดล:

    public bool? Active { get; set; } 

ใน DbContext OnModelCreating คุณเพิ่มค่าเริ่มต้น

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Foundation>()
            .Property(b => b.Active)
            .HasDefaultValueSql("1");

        base.OnModelCreating(modelBuilder);
    }

ส่งผลให้เกิดสิ่งต่อไปนี้ในฐานข้อมูล

ป้อนคำอธิบายรูปภาพที่นี่

หมายเหตุ: ถ้าคุณไม่มี null (bool?) สำหรับคุณคุณจะได้รับคำเตือนดังต่อไปนี้

The 'bool' property 'Active' on entity type 'Foundation' is configured with a database-generated default. This default will always be used for inserts when the property has the value 'false', since this is the CLR default for the 'bool' type. Consider using the nullable 'bool?' type instead so that the default will only be used for inserts when the property value is 'null'.

-3

ฉันพบว่าเพียงแค่ใช้คุณสมบัติเริ่มต้นอัตโนมัติกับคุณสมบัติเอนทิตีก็เพียงพอที่จะทำงานให้เสร็จได้

ตัวอย่างเช่น:

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

2
คุณคิดว่ามันจะใช้ได้กับรหัสก่อน แต่มันไม่เหมาะสำหรับฉันที่ใช้ EF 6.2
user1040323

-4

อืม ... ฉันทำ DB ก่อนและในกรณีนี้มันง่ายกว่ามาก EF6 ใช่มั้ย เพียงเปิดโมเดลของคุณคลิกขวาที่คอลัมน์ที่คุณต้องการตั้งค่าเริ่มต้นเลือกคุณสมบัติและคุณจะเห็นช่อง "DefaultValue" เพียงแค่กรอกและบันทึก มันจะตั้งรหัสให้คุณ

ระยะทางของคุณอาจแตกต่างกันในรหัสก่อนแม้ว่าฉันไม่ได้ทำงานกับที่

ปัญหาเกี่ยวกับการแก้ปัญหาอื่น ๆ มากมายคือในขณะที่พวกเขาอาจทำงานในขั้นต้นทันทีที่คุณสร้างแบบจำลองใหม่มันจะโยนรหัสที่กำหนดเองใด ๆ ที่คุณใส่เข้าไปในไฟล์ที่สร้างด้วยเครื่อง

วิธีนี้ใช้ได้โดยเพิ่มคุณสมบัติพิเศษให้กับไฟล์ edmx:

<EntityType Name="Thingy">
  <Property Name="Iteration" Type="Int32" Nullable="false" **DefaultValue="1"** />

และโดยการเพิ่มรหัสที่จำเป็นในการสร้าง:

public Thingy()
{
  this.Iteration = 1;

-5

ตั้งค่าเริ่มต้นสำหรับคอลัมน์ในตารางในเซิร์ฟเวอร์ MSSQL และในแอตทริบิวต์รหัสเพิ่มระดับเช่นนี้:

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]

สำหรับคุณสมบัติเดียวกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.