У меня есть DefaultAttribute
определяется следующим образом:Использование пользовательского атрибута в EF7 (ядра) OnModelCreating
[AttributeUsage(AttributeTargets.Property)]
public class DefaultAttribute : Attribute
{
/// <summary>
/// Specifies this property has a default value upon creation.
/// </summary>
/// <param name="defaultValue">The default value of the property.</param>
/// <param name="useAsLiteral">Set to true if the value is <em>not</em> quoted in the DDL.</param>
public DefaultAttribute(object defaultValue, bool useAsLiteral = false)
{
DefaultValue = defaultValue;
UseAsLiteral = useAsLiteral;
}
public object DefaultValue { get; private set; }
/// <summary>
/// True if the default value is not quoted in the DDL
/// </summary>
public bool UseAsLiteral { get; private set; }
}
Я украсили несколько моих сущностей с этим атрибутом, например, так:
public class MyEntity
{
. . . (other properties) . . .
[StringLength(200)]
[Required]
[Default("My Default Description!")]
public string Description { get; set; }
}
Тогда , в моем методе OnModelCreating в контексте моей базы данных я написал следующий код:
//examine custom annotations for shaping the schema in the database.
foreach (var entityType in builder.Model.GetEntityTypes())
foreach (var property in entityType.GetProperties())
{
var annotations = property.GetAnnotations();
// evaluate default values
var defaultAnnotation = annotations.FirstOrDefault(x => x.Name == typeof(DefaultAttribute).FullName);
if (defaultAnnotation != null)
{
var defaultValue = defaultAnnotation.Value as DefaultAttribute;
if (defaultValue == null) continue;
if (defaultValue.UseAsLiteral)
property.Npgsql().DefaultValueSql = defaultValue.DefaultValue.ToString();
else
property.Npgsql().DefaultValue = defaultValue.DefaultValue;
}
}
Мое ожидание при добавлении миграции (и последующем обновлении базы данных) заключается в том, что было бы значение по умолчанию «My Default Description!» для столбца Description
MyEntity
... однако, это не так.
Я не получаю никаких ошибок, но это не так, как я подозревал, и переход на OnModelCreating
с точкой останова также необъяснимо сложно.
Я делаю это правильно? Это просто не работает? Это просто не поддерживается в EF7? Или это не поддерживается в моей реализации PostgreSQL? Любое понимание было бы оценено.
UPDATE Использование @ ответ IvanStoev, я был в состоянии получить эту работу с некоторыми незначительными modifiactions (Отражение в .NET Ядра немного отличается от традиционного):
//examine custom annotations for shaping the schema in the database.
foreach (var entityType in builder.Model.GetEntityTypes())
foreach (var property in entityType.GetProperties())
{
var memberInfo = property.PropertyInfo ?? (MemberInfo)property.FieldInfo;
var defaultValue = memberInfo?.GetCustomAttribute<DefaultAttribute>();
if (defaultValue == null) continue;
if (defaultValue.UseAsLiteral)
property.Npgsql().DefaultValueSql = defaultValue.DefaultValue.ToString();
else
property.Npgsql().DefaultValue = defaultValue.DefaultValue;
}
Это работает как чавканье ,
Обратите внимание, что нет никакой реальной причины, чтобы сделать '.Npgsql()' - это для установки значения по умолчанию только для Npgsql, когда нацеливание на несколько баз данных. В большинстве случаев вам просто нужно выполнить 'property.HasDefaultValue (...)' (см. Https://docs.microsoft.com/en-us/ef/core/modeling/relational/default-values) –