Les réponses ci-dessus ont vraiment aidé, mais n'ont fourni qu'une partie de la solution. Le problème majeur est que dès que vous supprimez l'attribut Valeur par défaut, la contrainte sur la colonne dans la base de données ne sera pas supprimée. La valeur par défaut précédente restera donc toujours dans la base de données.
Voici une solution complète au problème, y compris la suppression des contraintes SQL sur la suppression des attributs. Je réutilise également le natif de .NET FrameworkDefaultValue
attribut .
Usage
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[DefaultValue("getutcdate()")]
public DateTime CreatedOn { get; set; }
Pour que cela fonctionne, vous devez mettre à jour IdentityModels.cs et Configuration.cs fichiers
Fichier IdentityModels.cs
Ajoutez / mettez à jour cette méthode dans votre ApplicationDbContext
classe
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);
}
Fichier Configuration.cs
Mettez à jour votre Configuration
constructeur de classe en enregistrant un générateur SQL personnalisé, comme ceci:
internal sealed class Configuration : DbMigrationsConfiguration<ApplicationDbContext>
{
public Configuration()
{
// DefaultValue Sql Generator
SetSqlGenerator("System.Data.SqlClient", new DefaultValueSqlServerMigrationSqlGenerator());
}
}
Ensuite, ajoutez une classe de générateur SQL personnalisée (vous pouvez l'ajouter au fichier Configuration.cs ou à un fichier distinct)
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;
}
}
this.Active = true;
? Je pense que la valeur DB aura la priorité lors de la récupération, mais attention si nouveau, puis attacher une entité pour une mise à jour sans récupération d'abord, car le suivi des modifications peut voir cela comme si vous vouliez mettre à jour la valeur. Commentaire parce que je n'ai pas utilisé EF depuis longtemps, et j'ai l'impression que c'est une photo dans le noir.