是否有“优雅”的方式给特定的属性一个默认值?

也许是DataAnnotations,比如:

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

谢谢你!


当前回答

我发现,只需在实体属性上使用Auto-Property Initializer就足以完成工作。

例如:

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

其他回答

即使在。net Core 1.0中,当你使用代码优先的方法时,也可以设置默认值。请参阅下面的代码片段。

using System.ComponentModel;
[DefaultValue(true)]
public bool Active { get; set; }

阅读:微软官方文档

嗯…我先做DB,在这种情况下,这实际上要简单得多。EF6对吧?只需打开你的模型,右键单击你想要设置默认值的列,选择属性,你会看到一个“DefaultValue”字段。填好并保存。它将为您设置代码。

你的里程数可能会在代码上有所不同,但我没有使用过这种方法。

许多其他解决方案的问题是,虽然它们最初可能有效,但一旦您重新构建模型,它就会抛出您插入到机器生成文件中的任何自定义代码。

这个方法通过在edmx文件中添加一个额外的属性来工作:

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

通过在构造函数中添加必要的代码:

public Thingy()
{
  this.Iteration = 1;

上面的答案确实有帮助,但只提供了部分解决方案。 主要问题是,一旦您删除了默认值属性,对数据库中列的约束就不会被删除。因此,之前的默认值仍将保留在数据库中。

下面是该问题的完整解决方案,包括删除属性删除上的SQL约束。 我还重用了. net Framework的原生DefaultValue属性。

使用

[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文件

通过注册自定义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;

    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)
    {
        if (column.Annotations.TryGetValue("SqlDefaultValue", out var 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 tableNameSplitByDot = tableName.Split('.');
        var tableSchema = tableNameSplitByDot[0];
        var tablePureName = tableNameSplitByDot[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++;
        return str;
    }
}

在MSSQL Server中为表中的列设置默认值,并在类代码中添加属性,如下所示:

[DatabaseGenerated (DatabaseGeneratedOption断层扫描)。]

对于相同的性质。

已经有一段时间了,但给别人留个字条。 我实现了所需要的属性,我装饰我的模型类字段的属性,因为我想要。

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

得到了这两篇文章的帮助:

EF在CodePlex Andy Mehalick博客

我做了什么:

定义属性

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