Кто-нибудь знает, как я могу указать значение по умолчанию для свойства DateTime с помощью атрибута System.ComponentModel DefaultValue?
например, я пробую это:
[DefaultValue(typeof(DateTime),DateTime.Now.ToString("yyyy-MM-dd"))]
public DateTime DateCreated { get; set; }
И он ожидает, что значение будет постоянным выражением.
Это в контексте использования с динамическими данными ASP.NET. Я не хочу формировать столбец DateCreated, а просто предоставляю DateTime.Now, если его нет. Я использую Entity Framework в качестве уровня данных
Привет,
Андрей
источник
get
можно упростить до:return dateCreated ?? DateTime.Now;
Добавьте ниже в свойство DateTime
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
источник
Нет причин, по которым я могу придумать, что это невозможно сделать с помощью атрибута. Это может быть в отставке Microsoft. Кто знает.
Лучшее решение, которое я нашел, - использовать параметр defaultValueSql при первой миграции кода.
CreateTable( "dbo.SomeTable", c => new { TheDateField = c.DateTime(defaultValueSql: "GETDATE()") });
Мне не нравится часто используемое решение по установке его в конструкторе класса сущности, потому что, если что-либо, кроме Entity Framework, вставляет запись в эту таблицу, поле даты не получит значения по умолчанию. И идея использования триггера для решения этого дела мне кажется неправильной.
источник
Я тестировал это на ядре EF 2.1
Здесь вы не можете использовать ни соглашения, ни аннотации данных. Вы должны использовать Fluent 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()"); } }
Официальный документ
источник
Можно и довольно просто:
за
DateTime.MinValue
[System.ComponentModel.DefaultValue(typeof(DateTime), "")]
для любого другого значения в качестве последнего аргумента
DefaultValueAttribute
укажите строку, представляющую желаемое значение DateTime.Это значение должно быть постоянным выражением и требуется для создания объекта (
DateTime
) с помощьюTypeConverter
.источник
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)
Простым решением, если вы используете Entity Framework, является добавление частичного класса и определение конструктора для объекта, поскольку структура его не определяет. Например, если у вас есть объект с именем Example, вы должны поместить следующий код в отдельный файл.
namespace EntityExample { public partial class Example : EntityObject { public Example() { // Initialize certain default values here. this._DateCreated = DateTime.Now; } } }
источник
Думаю, самое простое решение - установить
Created DATETIME2 NOT NULL DEFAULT GETDATE()
в объявлении столбца и в конструкторе VS2010 EntityModel установите соответствующее свойство столбца StoreGeneratedPattern = Computed .
источник
Хорошим предложением является создание нового класса атрибутов. В моем случае я хотел указать 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.
источник
Просто подумайте о том, чтобы установить его значение в конструкторе вашего класса сущности.
public class Foo { public DateTime DateCreated { get; set; } public Foo() { DateCreated = DateTime.Now; } }
источник
Datetime
перед этим мне пришлось установить свойство, допускающее значение NULL.Мне нужна была отметка времени 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 см. Этот замечательный пост в блоге
источник
using System.ComponentModel.DataAnnotations.Schema;
[DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime CreatedOn { get; private set; }
источник
Есть способ. Добавьте эти классы:
DefaultDateTimeValueAttribute.cs
using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using Custom.Extensions; namespace Custom.DefaultValueAttributes { /// <summary> /// This class's DefaultValue attribute allows the programmer to use DateTime.Now as a default value for a property. /// Inspired from https://code.msdn.microsoft.com/A-flexible-Default-Value-11c2db19. /// </summary> [AttributeUsage(AttributeTargets.Property)] public sealed class DefaultDateTimeValueAttribute : DefaultValueAttribute { public string DefaultValue { get; set; } private object _value; public override object Value { get { if (_value == null) return _value = GetDefaultValue(); return _value; } } /// <summary> /// Initialized a new instance of this class using the desired DateTime value. A string is expected, because the value must be generated at runtime. /// Example of value to pass: Now. This will return the current date and time as a default value. /// Programmer tip: Even if the parameter is passed to the base class, it is not used at all. The property Value is overridden. /// </summary> /// <param name="defaultValue">Default value to render from an instance of <see cref="DateTime"/></param> public DefaultDateTimeValueAttribute(string defaultValue) : base(defaultValue) { DefaultValue = defaultValue; } public static DateTime GetDefaultValue(Type objectType, string propertyName) { var property = objectType.GetProperty(propertyName); var attribute = property.GetCustomAttributes(typeof(DefaultDateTimeValueAttribute), false) ?.Cast<DefaultDateTimeValueAttribute>() ?.FirstOrDefault(); return attribute.GetDefaultValue(); } private DateTime GetDefaultValue() { // Resolve a named property of DateTime, like "Now" if (this.IsProperty) { return GetPropertyValue(); } // Resolve a named extension method of DateTime, like "LastOfMonth" if (this.IsExtensionMethod) { return GetExtensionMethodValue(); } // Parse a relative date if (this.IsRelativeValue) { return GetRelativeValue(); } // Parse an absolute date return GetAbsoluteValue(); } private bool IsProperty => typeof(DateTime).GetProperties() .Select(p => p.Name).Contains(this.DefaultValue); private bool IsExtensionMethod => typeof(DefaultDateTimeValueAttribute).Assembly .GetType(typeof(DefaultDateTimeExtensions).FullName) .GetMethods() .Where(m => m.IsDefined(typeof(ExtensionAttribute), false)) .Select(p => p.Name).Contains(this.DefaultValue); private bool IsRelativeValue => this.DefaultValue.Contains(":"); private DateTime GetPropertyValue() { var instance = Activator.CreateInstance<DateTime>(); var value = (DateTime)instance.GetType() .GetProperty(this.DefaultValue) .GetValue(instance); return value; } private DateTime GetExtensionMethodValue() { var instance = Activator.CreateInstance<DateTime>(); var value = (DateTime)typeof(DefaultDateTimeValueAttribute).Assembly .GetType(typeof(DefaultDateTimeExtensions).FullName) .GetMethod(this.DefaultValue) .Invoke(instance, new object[] { DateTime.Now }); return value; } private DateTime GetRelativeValue() { TimeSpan timeSpan; if (!TimeSpan.TryParse(this.DefaultValue, out timeSpan)) { return default(DateTime); } return DateTime.Now.Add(timeSpan); } private DateTime GetAbsoluteValue() { DateTime value; if (!DateTime.TryParse(this.DefaultValue, out value)) { return default(DateTime); } return value; } } }
DefaultDateTimeExtensions.cs
using System; namespace Custom.Extensions { /// <summary> /// Inspired from https://code.msdn.microsoft.com/A-flexible-Default-Value-11c2db19. See usage for more information. /// </summary> public static class DefaultDateTimeExtensions { public static DateTime FirstOfYear(this DateTime dateTime) => new DateTime(dateTime.Year, 1, 1, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond); public static DateTime LastOfYear(this DateTime dateTime) => new DateTime(dateTime.Year, 12, 31, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond); public static DateTime FirstOfMonth(this DateTime dateTime) => new DateTime(dateTime.Year, dateTime.Month, 1, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond); public static DateTime LastOfMonth(this DateTime dateTime) => new DateTime(dateTime.Year, dateTime.Month, DateTime.DaysInMonth(dateTime.Year, dateTime.Month), dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond); } }
И используйте DefaultDateTimeValue в качестве атрибута ваших свойств. Значение для ввода в ваш атрибут проверки - это такие вещи, как «Сейчас», которые будут отображаться во время выполнения из экземпляра DateTime, созданного с помощью Activator. Исходный код вдохновлен этим потоком: https://code.msdn.microsoft.com/A-f flexible-Default-Value-11c2db19 . Я изменил его, чтобы мой класс унаследовал атрибут DefaultValueAttribute вместо ValidationAttribute.
источник
Просто нашел это в поисках чего-то другого, но в новой версии C # вы можете использовать для этого еще более короткую версию:
public DateTime DateCreated { get; set; } = DateTime.Now;
источник
Я столкнулся с той же проблемой, но тот, который подходит мне лучше всего, ниже:
public DateTime CreatedOn { get; set; } = DateTime.Now;
источник
public DateTime DateCreated { get { return (this.dateCreated == default(DateTime)) ? this.dateCreated = DateTime.Now : this.dateCreated; } set { this.dateCreated = value; } } private DateTime dateCreated = default(DateTime);
источник
Как вы справляетесь с этим в настоящий момент, зависит от того, какую модель вы используете Linq to SQL или EntityFramework?
В L2S можно добавить
public partial class NWDataContext { partial void InsertCategory(Category instance) { if(Instance.Date == null) Instance.Data = DateTime.Now; ExecuteDynamicInsert(instance); } }
EF немного сложнее, см. Http://msdn.microsoft.com/en-us/library/cc716714.aspx для получения дополнительной информации о бизнес-логике EF.
источник
Я знаю, что этот пост немного устарел, но у меня есть предложение, которое может некоторым помочь.
Я использовал Enum, чтобы определить, что установить в конструкторе атрибутов.
Декларация собственности:
[DbProperty(initialValue: EInitialValue.DateTime_Now)] public DateTime CreationDate { get; set; }
Конструктор недвижимости:
Public Class DbProperty Inherits System.Attribute Public Property InitialValue As Object Public Sub New(ByVal initialValue As EInitialValue) Select Case initialValue Case EInitialValue.DateTime_Now Me.InitialValue = System.DateTime.Now Case EInitialValue.DateTime_Min Me.InitialValue = System.DateTime.MinValue Case EInitialValue.DateTime_Max Me.InitialValue = System.DateTime.MaxValue End Select End Sub End Class
Enum:
источник
Я думаю, вы можете сделать это, используя
StoreGeneratedPattern = Identity
(набор в окне конструктора свойств модели).Я бы не догадался, как это можно сделать, но, пытаясь понять это, я заметил, что некоторые из моих столбцов дат уже имеют значения по умолчанию,
CURRENT_TIMESTAMP()
а некоторые нет. Проверяя модель, я вижу, что единственное различие между двумя столбцами, помимо имени, состоит в том, что тот, который получает значение по умолчанию,StoreGeneratedPattern
установлен наIdentity
.Я бы не ожидал, что так будет, но, прочитав описание, это имеет смысл:
Кроме того, хотя при этом столбец базы данных имеет значение по умолчанию «сейчас», я предполагаю, что на самом деле он не устанавливает свойство
DateTime.Now
в POCO. Для меня это не было проблемой, так как у меня есть настроенный файл .tt, который ужеDateTime.Now
автоматически устанавливает все мои столбцы даты (на самом деле нетрудно изменить файл .tt самостоятельно, особенно если у вас есть ReSharper и есть подсветка синтаксиса плагин. (Более новые версии VS могут уже выделять синтаксис .tt файлов, не уверен.))Для меня проблема заключалась в следующем: как сделать столбец базы данных значением по умолчанию, чтобы существующие запросы, в которых этот столбец опущен, все равно работали? И вышеуказанная настройка сработала для этого.
Я еще не тестировал это, но также возможно, что установка этого будет мешать установке вашего собственного явного значения. (Я впервые наткнулся на это, потому что EF6 Database First написала модель для меня таким образом.)
источник
В C # версии 6 можно указать значение по умолчанию
public DateTime fieldname { get; set; } = DateTime.Now;
источник
С EF 7:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] Column(TypeName = "datetime2")] DateTime? Dateadded { get; set; }
сценарий миграции:
AlterColumn("myschema.mytable", "Dateadded", c => c.DateTime(nullable: false, precision: 7, storeType: "datetime2", defaultValueSql: "getutcdate()"));
результат:
источник
Я также хотел этого и придумал это решение (я использую только часть даты - время по умолчанию не имеет смысла в качестве значения по умолчанию для PropertyGrid):
public class DefaultDateAttribute : DefaultValueAttribute { public DefaultDateAttribute(short yearoffset) : base(DateTime.Now.AddYears(yearoffset).Date) { } }
Это просто создает новый атрибут, который вы можете добавить к свойству DateTime. Например, если по умолчанию используется DateTime.Now.Date:
[DefaultDate(0)]
источник