2017-08-15 4 views
2

私はAzureのモバイルサービスで使用している次のコード、最初のEntity Frameworkのコードを持っている:EFコードファーストとAzureでデフォルトの制約を作成する方法は?

public class BookContext : DbContext 
{ 
private const string connectionStringName = "Name=MS_TableConnectionString"; 

public BookContext() : base(connectionStringName) { } 

// The collections queried directly. 
public DbSet<Book> Books{ get; set; } 

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    // Standard code to add the "service" columns such as CreatedAt, UpdatedAt, and Deleted. 
    modelBuilder.Conventions.Add(
     new AttributeToColumnAnnotationConvention<TableColumnAttribute, string>(
      "ServiceTableColumn", (property, attributes) => attributes.Single().ColumnType.ToString())); 

    // Add a default value 0 on the Deleted column. The following code does not work. 
    modelBuilder.Entity<Book>() 
       .Property(p => p.Deleted) 
       .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed); 
} 
} 

上述したように、コードが削除された列にデフォルトの制約を追加することになったが、それがないています何もしないでください。私は、コード最初のEFとして、次のSQL文と同等のものを達成したいと思います:

ALTER TABLE dbo.Books ADD CONSTRAINT DF_BooksDeleted DEFAULT 0 FOR Deleted 

どうやら、私は何か間違ったことしなければなりません。誰かが私を正しい方向に向けることができますか?

答えて

1

AFAIKでは、データベースのデフォルト値はEFコアの一部です。詳細はDefault Valuesを参照してください。

要件に基づいて、Azure Mobileサービステーブルのシステム列Deletedのデフォルト値を設定しようとしています。

MyEntityTableSqlGenerator.cs

public class MyEntityTableSqlGenerator : EntityTableSqlGenerator 
{ 
    protected override void UpdateTableColumn(ColumnModel columnModel, TableColumnType tableColumnType) 
    { 
     //for system column deleted 
     switch (tableColumnType) 
     { 
      case TableColumnType.Deleted: 
       columnModel.DefaultValue = 0; 
       break; 
     } 
     base.UpdateTableColumn(columnModel, tableColumnType); 
    } 

    protected override void Generate(CreateTableOperation createTableOperation) 
    { 
     //for your custom columns 
     foreach (ColumnModel column in createTableOperation.Columns) 
     { 
      TableColumnType tableColumnType = this.GetTableColumnType(column); 
      if (tableColumnType == TableColumnType.None) 
      { 
       if (column.Annotations.Keys.Contains("DefaultValue")) 
       { 
        var value = Convert.ChangeType(column.Annotations["DefaultValue"].NewValue, column.ClrDefaultValue.GetType()); 
        column.DefaultValue = value; 
       } 
      } 
     } 

     //for system columns 
     base.Generate(createTableOperation); 
    } 
} 

変更Configuration.csとカスタムSqlGeneratorを追加します。私はあなたがEntityTableSqlGenerator.csをオーバーライドし、次のようにシステム列Deletedとカスタム列にデフォルト値を設定するためのロジックを追加することができると仮定しました:

public Configuration() 
{ 
    SetSqlGenerator("System.Data.SqlClient", new MyEntityTableSqlGenerator()); 
} 

次に、あなたのを変更方法を次のように

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    //set default value for your custom columns 
    modelBuilder.Entity<Tag>() 
     .Property(p => p.Status) 
     .HasColumnName("Status") 
     .HasColumnAnnotation("DefaultValue","false"); 

    modelBuilder.Conventions.Add(
     new AttributeToColumnAnnotationConvention<TableColumnAttribute, string>(
      "ServiceTableColumn", (property, attributes) => attributes.Single().ColumnType.ToString())); 

} 

結果:

enter image description here

+1

おかげでブルース。あなたのコードは素晴らしいです。実際には、EntityTableSqlGeneratorを追加してOnModelCreatingをそのままにしておく必要がありました。削除された列のデフォルトの制約は、とにかく作成されました。 OnModelCreatingの[削除済み]列のデフォルト値を設定する必要があるのはなぜですか? – ata6502

+0

私は 'Deleted'カラムにデフォルトの制約がないと思いました。カスタム列のデフォルト値を設定する場合は、残りの部分を参照できます。 –

+0

MyEntityTableSqlGeneratorの目的は、Default制約の値を設定することです。 OnModelCreatingの目的は、Default制約を作成することです。それが正しいか?もしそうなら、既定の制約を作成したOnModelCreatingをすでに実行している可能性があります。 – ata6502

関連する問題