Установка значения по умолчанию для свойства DateTime в DateTime.Now внутри System.ComponentModel Значение по умолчанию Attrbute - PullRequest
80 голосов
/ 27 марта 2009

Кто-нибудь знает, как я могу указать значение по умолчанию для свойства DateTime, используя атрибут System.ComponentModel DefaultValue?

например, я пытаюсь это:

[DefaultValue(typeof(DateTime),DateTime.Now.ToString("yyyy-MM-dd"))]
public DateTime DateCreated { get; set; }

И ожидает, что значение будет константным выражением.

Это в контексте использования с ASP.NET Dynamic Data. Я не хочу создавать эшафот для столбца DateCreated, а просто предоставляю DateTime.Now, если он отсутствует. Я использую Entity Framework в качестве уровня данных

Приветствия

Andrew

Ответы [ 19 ]

84 голосов
/ 27 марта 2009

Вы не можете сделать это с атрибутом, потому что это просто метаинформация, сгенерированная во время компиляции. Просто добавьте код в конструктор, чтобы инициализировать дату, если необходимо, создайте триггер и обработайте пропущенные значения в базе данных или внедрите метод получения таким образом, чтобы он возвращал DateTime.Now, если поле поддержки не инициализировано.

public DateTime DateCreated
{
   get
   {
      return this.dateCreated.HasValue
         ? this.dateCreated.Value
         : DateTime.Now;
   }

   set { this.dateCreated = value; }
}

private DateTime? dateCreated = null;
19 голосов
/ 16 апреля 2015

Нет причин, по которым я могу придумать, что это невозможно сделать с помощью атрибута. Это может быть в отставании Microsoft. Кто знает.

Лучшее решение, которое я нашел, - это использовать параметр defaultValueSql в первой миграции кода.

CreateTable(
    "dbo.SomeTable",
    c => new
        {
            TheDateField = c.DateTime(defaultValueSql: "GETDATE()")
        });

Мне не нравится часто упоминаемое решение его установки в конструкторе класса сущности, потому что если что-то кроме Entity Framework вставит запись в эту таблицу, поле даты не получит значение по умолчанию. И идея использования триггера для обработки этого случая мне просто кажется неправильной.

18 голосов
/ 19 мая 2017

Добавьте ниже к свойству DateTime

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
10 голосов
/ 15 февраля 2012

Это возможно и довольно просто:

для DateTime.MinValue

[System.ComponentModel.DefaultValue(typeof(DateTime), "")]

для любого другого значения в качестве последнего аргумента DefaultValueAttribute укажите строку, которая представляет желаемое значение DateTime.

Это значение должно быть выражением константы и требуется для создания объекта (DateTime) с использованием TypeConverter.

9 голосов
/ 22 сентября 2018

Я проверял это на EF core 2.1

Здесь вы не можете использовать условные обозначения или аннотации данных. Вы должны использовать Свободный API .

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .Property(b => b.Created)
            .HasDefaultValueSql("getdate()");
    }
}

Официальный документ

6 голосов
/ 18 ноября 2010

Простым решением, если вы используете Entity Framework, является добавление частичного класса и определение конструктора для объекта, поскольку среда не определяет его. Например, если у вас есть сущность с именем Example, вы поместите следующий код в отдельный файл.

namespace EntityExample
{
    public partial class Example : EntityObject
    {
        public Example()
        {
            // Initialize certain default values here.
            this._DateCreated = DateTime.Now;
        }
    }
}
5 голосов
/ 17 апреля 2012

Я думаю, что самое простое решение - установить

Created DATETIME2 NOT NULL DEFAULT GETDATE()

в объявлении столбца и в конструкторе EntityModel VS2010 установите соответствующее свойство столбца StoreGeneratedPattern = Computed .

4 голосов
/ 24 апреля 2013

Просто рассмотрите возможность установки его значения в конструкторе класса вашей сущности

public class Foo
{
       public DateTime DateCreated { get; set; }
       public Foo()
       {
           DateCreated = DateTime.Now;
       }

}
3 голосов
/ 04 июня 2011

Создание нового класса атрибутов является хорошим предложением. В моем случае я хотел указать «default (DateTime)» или «DateTime.MinValue», чтобы сериализатор Newtonsoft.Json игнорировал элементы DateTime без реальных значений.

[JsonProperty( DefaultValueHandling = DefaultValueHandling.Ignore )]
[DefaultDateTime]
public DateTime EndTime;

public class DefaultDateTimeAttribute : DefaultValueAttribute
{
    public DefaultDateTimeAttribute()
        : base( default( DateTime ) ) { }

    public DefaultDateTimeAttribute( string dateTime )
        : base( DateTime.Parse( dateTime ) ) { }
}

Без атрибута DefaultValue сериализатор JSON выведет «1/1/0001 12:00:00 AM», даже если был установлен параметр DefaultValueHandling.Ignore.

3 голосов
/ 25 мая 2011

Мне понадобилась метка времени UTC в качестве значения по умолчанию, и я изменил решение Дэниела следующим образом:

    [Column(TypeName = "datetime2")]
    [XmlAttribute]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
    [Display(Name = "Date Modified")]
    [DateRange(Min = "1900-01-01", Max = "2999-12-31")]
    public DateTime DateModified {
        get { return dateModified; }
        set { dateModified = value; } 
    }
    private DateTime dateModified = DateTime.Now.ToUniversalTime();

Об обучающей программе DateRangeAttribute см. это потрясающее сообщение в блоге

...