Définition de la valeur par défaut d’une propriété DateTime sur DateTime.Now dans la valeur par défaut System.ComponentModel Attrbute

Est-ce que quelqu’un sait comment je peux spécifier la valeur par défaut pour une propriété DateTime à l’aide de l’atsortingbut System.ComponentModel DefaultValue?

par exemple j’essaye ceci:

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

Et il s’attend à ce que la valeur soit une expression constante.

Ceci est dans le contexte de l’utilisation avec ASP.NET Dynamic Data. Je ne veux pas échafauder la colonne DateCreated mais simplement fournir le DateTime.Now s’il n’est pas présent. J’utilise Entity Framework comme couche de données

À votre santé,

Andrew

Vous ne pouvez pas faire cela avec un atsortingbut car ce ne sont que des méta-informations générées au moment de la compilation. Ajoutez simplement du code au constructeur pour initialiser la date si nécessaire, créez un déclencheur et gérez les valeurs manquantes dans la firebase database ou implémentez le getter de manière à ce qu’il renvoie DateTime.Maintenant si le champ de sauvegarde n’est pas initialisé.

 public DateTime DateCreated { get { return this.dateCreated.HasValue ? this.dateCreated.Value : DateTime.Now; } set { this.dateCreated = value; } } private DateTime? dateCreated = null; 

Il n’y a aucune raison pour que je puisse imaginer que cela ne devrait pas être possible avec un atsortingbut. Cela pourrait être dans le carnet de commandes de Microsoft. Qui sait.

La meilleure solution que j’ai trouvée consiste à utiliser le paramètre defaultValueSql dans la première migration du code.

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

Je n’aime pas la solution souvent utilisée pour la définir dans le constructeur de classe d’entités car si quelque chose d’autre que Entity Framework colle un enregistrement dans cette table, le champ de date n’obtiendra pas de valeur par défaut. Et l’idée d’utiliser un déclencheur pour gérer ce cas me semble tout à fait erronée.

C’est possible et assez simple:

pour DateTime.MinValue

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

pour toute autre valeur en tant que dernier argument de DefaultValueAtsortingbute spécifiez la chaîne qui représente la valeur DateTime souhaitée.

Cette valeur doit être une expression constante et est requirejse pour créer un object ( DateTime ) à l’aide de TypeConverter .

Une solution simple si vous utilisez Entity Framework est l’ajout d’une classe partielle et la définition d’un constructeur pour l’entité car le framework n’en définit pas. Par exemple, si vous avez une entité nommée Exemple, vous devez placer le code suivant dans un fichier séparé.

 namespace EntityExample { public partial class Example : EntityObject { public Example() { // Initialize certain default values here. this._DateCreated = DateTime.Now; } } } 

Je pense que la solution la plus simple est de définir

 Created DATETIME2 NOT NULL DEFAULT GETDATE() 

dans la déclaration de colonne et dans VS2010 EntityModel Designer définit la propriété de colonne correspondante StoreGeneratedPattern = Computed .

Pensez simplement à définir sa valeur dans le constructeur de votre classe d’entités

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

J’avais besoin d’un horodatage UTC comme valeur par défaut et j’ai donc modifié la solution de Daniel comme ceci:

  [Column(TypeName = "datetime2")] [XmlAtsortingbute] [DisplayFormat(ApplyFormatInEditMode = true, DataFormatSsortingng = "{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(); 

Pour le tutoriel DateRangeAtsortingbute, consultez cet article de blog impressionnant

Créer une nouvelle classe d’atsortingbut est une bonne suggestion. Dans mon cas, je voulais spécifier «default (DateTime)» ou «DateTime.MinValue» pour que le sérialiseur Newtonsoft.Json ignore les membres DateTime sans valeurs réelles.

 [JsonProperty( DefaultValueHandling = DefaultValueHandling.Ignore )] [DefaultDateTime] public DateTime EndTime; public class DefaultDateTimeAtsortingbute : DefaultValueAtsortingbute { public DefaultDateTimeAtsortingbute() : base( default( DateTime ) ) { } public DefaultDateTimeAtsortingbute( ssortingng dateTime ) : base( DateTime.Parse( dateTime ) ) { } } 

Sans l’atsortingbut DefaultValue, le sérialiseur JSON afficherait “1/1/0001 12:00:00 AM” même si l’option DefaultValueHandling.Ignore était définie.

Ajouter ci-dessous à la propriété DateTime

 [DatabaseGenerated(DatabaseGeneratedOption.Computed)] 
 public DateTime DateCreated { get { return (this.dateCreated == default(DateTime)) ? this.dateCreated = DateTime.Now : this.dateCreated; } set { this.dateCreated = value; } } private DateTime dateCreated = default(DateTime); 

Comment vous gérez cela en ce moment dépend de quel modèle vous utilisez Linq to SQL ou EntityFramework?

Dans L2S, vous pouvez append

 public partial class NWDataContext { partial void InsertCategory(Category instance) { if(Instance.Date == null) Instance.Data = DateTime.Now; ExecuteDynamicInsert(instance); } } 

EF est un peu plus compliqué, voir http://msdn.microsoft.com/en-us/library/cc716714.aspx pour plus d’informations sur la logique de gestion EF.

Je viens juste de trouver cela pour trouver quelque chose de différent, mais dans la nouvelle version C #, vous pouvez utiliser une version encore plus courte pour cela:

 public DateTime DateCreated { get; set; } = DateTime.Now; 

Je sais que cet article est un peu vieux, mais vous avez une suggestion qui pourrait aider certains.

J’ai utilisé un Enum pour déterminer quoi définir dans le constructeur d’atsortingbut.

Déclaration de propriété:

 [DbProperty(initialValue: EInitialValue.DateTime_Now)] public DateTime CreationDate { get; set; } 

Constructeur immobilier:

 Public Class DbProperty Inherits System.Atsortingbute 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:

 Public Enum EInitialValue DateTime_Now DateTime_Min DateTime_Max End Enum 

Il y a un moyen. Ajoutez ces classes:

DefaultDateTimeValueAtsortingbute.cs

 using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Reflection; using System.Runtime.ComstackrServices; using Custom.Extensions; namespace Custom.DefaultValueAtsortingbutes { ///  /// This class's DefaultValue atsortingbute 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. ///  [AtsortingbuteUsage(AtsortingbuteTargets.Property)] public sealed class DefaultDateTimeValueAtsortingbute : DefaultValueAtsortingbute { public ssortingng DefaultValue { get; set; } private object _value; public override object Value { get { if (_value == null) return _value = GetDefaultValue(); return _value; } } ///  /// Initialized a new instance of this class using the desired DateTime value. A ssortingng 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. ///  /// Default value to render from an instance of  public DefaultDateTimeValueAtsortingbute(ssortingng defaultValue) : base(defaultValue) { DefaultValue = defaultValue; } public static DateTime GetDefaultValue(Type objectType, ssortingng propertyName) { var property = objectType.GetProperty(propertyName); var atsortingbute = property.GetCustomAtsortingbutes(typeof(DefaultDateTimeValueAtsortingbute), false) ?.Cast() ?.FirstOrDefault(); return atsortingbute.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(DefaultDateTimeValueAtsortingbute).Assembly .GetType(typeof(DefaultDateTimeExtensions).FullName) .GetMethods() .Where(m => m.IsDefined(typeof(ExtensionAtsortingbute), false)) .Select(p => p.Name).Contains(this.DefaultValue); private bool IsRelativeValue => this.DefaultValue.Contains(":"); private DateTime GetPropertyValue() { var instance = Activator.CreateInstance(); var value = (DateTime)instance.GetType() .GetProperty(this.DefaultValue) .GetValue(instance); return value; } private DateTime GetExtensionMethodValue() { var instance = Activator.CreateInstance(); var value = (DateTime)typeof(DefaultDateTimeValueAtsortingbute).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 { ///  /// Inspired from https://code.msdn.microsoft.com/A-flexible-Default-Value-11c2db19. See usage for more information. ///  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); } } 

Et utilisez DefaultDateTimeValue comme atsortingbut à vos propriétés. Les valeurs à saisir dans votre atsortingbut de validation sont des éléments tels que “Now”, qui seront affichés à l’exécution à partir d’une instance DateTime créée avec un activateur. Le code source est inspiré de ce sujet: https://code.msdn.microsoft.com/A-flexible-Default-Value-11c2db19 . Je l’ai modifié pour que ma classe hérite de DefaultValueAtsortingbute au lieu d’un ValidationAtsortingbute.

Je pense que vous pouvez le faire en utilisant StoreGeneratedPattern = Identity (défini dans la fenêtre de propriétés du concepteur de modèles).

Je n’aurais pas deviné que ce serait comment le faire, mais en essayant de le comprendre, j’ai remarqué que certaines de mes colonnes de dates étaient déjà définies par défaut sur CURRENT_TIMESTAMP() et d’autres non. En vérifiant le modèle, je constate que la seule différence entre les deux colonnes en plus du nom est que celui qui reçoit la valeur par défaut a StoreGeneratedPattern défini sur Identity .

Je ne m’attendais pas à ce que ce soit le cas, mais en lisant la description, cela a du sens:

Détermine si la colonne correspondante dans la firebase database sera générée automatiquement lors des opérations d’insertion et de mise à jour.

De plus, bien que la valeur par défaut de la colonne de la firebase database soit “now”, je suppose qu’elle ne définit pas la propriété comme étant DateTime.Now dans le POCO. Cela n’a pas été un problème pour moi car j’ai un fichier .tt personnalisé qui définit déjà toutes mes colonnes de date sur DateTime.Now automatiquement (il n’est en fait pas difficile de modifier le fichier .tt, surtout si vous avez ReSharper et obtenez un plugin de coloration syntaxique (les versions les plus récentes de VS peuvent déjà mettre en évidence des fichiers .tt en surbrillance, pas sûr.))

Le problème pour moi était: comment puis-je obtenir la colonne par défaut de la firebase database pour que les requêtes existantes qui omettent cette colonne fonctionnent toujours? Et le réglage ci-dessus a fonctionné pour cela.

Je ne l’ai pas encore testé, mais il est également possible que ce paramètre interfère avec la définition de votre propre valeur explicite. (Je ne suis tombé que sur cela parce que EF6 Database First a écrit le modèle pour moi de cette façon.)

Dans C # Version 6, il est possible de fournir une valeur par défaut

 public DateTime fieldname { get; set; } = DateTime.Now; 

en utilisant System.ComponentModel.DataAnnotations.Schema;

 [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime CreatedOn { get; private set; } 

Je voulais aussi cela et je suis venu avec cette solution (je n’utilise que la partie date – une heure par défaut n’a aucun sens en tant que propriété PropertyGrid par défaut):

 public class DefaultDateAtsortingbute : DefaultValueAtsortingbute { public DefaultDateAtsortingbute(short yearoffset) : base(DateTime.Now.AddYears(yearoffset).Date) { } } 

Cela crée simplement un nouvel atsortingbut que vous pouvez append à votre propriété DateTime. Par exemple, si la valeur par défaut est DateTime.Now.Date:

 [DefaultDate(0)]