2017-08-15 84 views
2

我有我使用的是Azure的移动服务下面的代码,第一实体框架代码:如何在EF code-first和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 Core的一部分,有关更多详细信息,请参阅Default Values

根据您的要求,您尝试为Azure移动服务表的系统列Deleted设置默认值。我认为你可以重写EntityTableSqlGenerator.cs并添加逻辑系统列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 :

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

然后,修改你的OnModelCreating方法如下:

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

相关问题