Die obigen Antworten haben wirklich geholfen, aber nur einen Teil der Lösung geliefert. Das Hauptproblem besteht darin, dass die Einschränkung für die Spalte in der Datenbank nicht entfernt wird, sobald Sie das Standardwertattribut entfernen. Der vorherige Standardwert bleibt also weiterhin in der Datenbank.
Hier finden Sie eine vollständige Lösung des Problems, einschließlich des Entfernens von SQL-Einschränkungen beim Entfernen von Attributen. Ich verwende auch das native DefaultValue
Attribut von .NET Framework erneut .
Verwendung
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[DefaultValue("getutcdate()")]
public DateTime CreatedOn { get; set; }
Damit dies funktioniert, müssen Sie die Dateien IdentityModels.cs und Configuration.cs aktualisieren
Datei IdentityModels.cs
Fügen Sie diese Methode in Ihrer ApplicationDbContext
Klasse hinzu / aktualisieren Sie sie
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);
}
Datei Configuration.cs
Aktualisieren Sie Ihren Configuration
Klassenkonstruktor, indem Sie einen benutzerdefinierten SQL-Generator wie folgt registrieren:
internal sealed class Configuration : DbMigrationsConfiguration<ApplicationDbContext>
{
public Configuration()
{
// DefaultValue Sql Generator
SetSqlGenerator("System.Data.SqlClient", new DefaultValueSqlServerMigrationSqlGenerator());
}
}
Fügen Sie als Nächstes eine benutzerdefinierte SQL-Generatorklasse hinzu (Sie können sie der Datei Configuration.cs oder einer separaten Datei hinzufügen ).
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;
? Ich denke, der DB-Wert hat beim Abrufen Vorrang, aber seien Sie vorsichtig, wenn Sie neu sind, und fügen Sie dann zuerst eine Entität für ein Update ohne Abruf hinzu, da die Änderungsverfolgung dies möglicherweise sieht, wenn Sie den Wert aktualisieren möchten. Kommentar, weil ich EF schon lange nicht mehr verwendet habe und ich denke, dass dies ein Schuss in die Dunkelheit ist.