programing

DateTime 속성의 기본값을 DateTime으로 설정하는 중입니다.이제 시스템 안으로 들어갑니다.ComponentModel 기본값 특성입니다.

telecom 2023. 4. 25. 21:53
반응형

DateTime 속성의 기본값을 DateTime으로 설정하는 중입니다.이제 시스템 안으로 들어갑니다.ComponentModel 기본값 특성입니다.

시스템을 사용하여 DateTime 속성의 기본값을 지정하는 방법을 아는 사람이 있습니까?ComponentModel DefaultValue 특성입니까?

예를 들어 다음과 같이 시도합니다.

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

그리고 이 값은 상수 표현식이 될 것으로 예상합니다.

이것은 ASP와 함께 사용하는 것과 관련이 있습니다.NET 동적 데이터입니다.DateCreated 열의 골격을 지정하는 것이 아니라 DateTime만 제공하고자 합니다.그게 없다면요엔티티 프레임워크를 데이터 계층으로 사용하고 있습니다.

건배.

속성은 컴파일 시 생성된 메타 정보일 뿐이므로 속성으로는 이 작업을 수행할 수 없습니다.필요한 경우 생성자에 코드를 추가하여 날짜를 초기화하거나, 트리거를 생성하여 데이터베이스에서 누락된 값을 처리하거나, Getter가 DateTime을 반환하는 방식으로 구현하기만 하면 됩니다.이제 지원 필드가 초기화되지 않은 경우입니다.

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

   set { this.dateCreated = value; }
}

private DateTime? dateCreated = null;

아래를 DateTime 속성에 추가하십시오.

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]

EF core 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()");
    }
}

공식 문서입니다.

속성을 통해서 불가능하다고 생각할 이유가 없습니다.마이크로소프트의 밀린 업무일 수 있습니다.누가 알겠어요?

제가 찾은 최고의 솔루션은 코드 첫 번째 마이그레이션에서 defaultValueSql 매개 변수를 사용하는 것입니다.

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

엔티티 프레임워크가 아닌 다른 항목이 해당 테이블에 레코드를 고정하면 날짜 필드가 기본값을 얻지 못하기 때문에 엔티티 클래스 생성자에 설정하는 참조 솔루션이 마음에 들지 않습니다.그리고 그 사건을 처리하기 위해 방아쇠를 당기는 생각은 잘못된 것 같아요

이것은 가능하고 매우 간단합니다.

해위에 대해서요DateTime.MinValue

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

인수로 다른 값을 지정합니다.DefaultValueAttribute날짜 시간입니다.

이 값은 상수 표현식이어야 하며 개체(예: 개체)를 만드는 데 필요합니다.DateTime을 사용합니다.TypeConverter요.

새로운 C# 버전에서는 더 짧은 버전을 사용할 수 있습니다.

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

엔터티 프레임워크를 사용하는 경우 간단한 솔루션은 부분 클래스를 추가하고 프레임워크가 생성자를 정의하지 않으므로 엔티티에 대한 생성자를 정의하는 것입니다.예를 들어, 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 = Calculated를 설정합니다.

새 특성 클래스를 만드는 것이 좋습니다.제 경우 'default(DateTime)' 또는 'DateTime'을 지정하려고 했습니다.뉴턴소프트를 만들 수 있게요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 속성이 없으면 DefaultValueHandling에도 불구하고 JSON 직렬화기는 "1/1/0001 12:00:00 AM"을 출력합니다.무시 옵션이 설정되었습니다.

엔티티 클래스의 생성자에서 해당 값을 설정하는 것을 고려하기만 하면 됩니다.

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

}

시스템을 사용합니다.ComponentModel입니다.데이터 주석입니다.스키마입니다;

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

저도 같은 문제에 직면했지만, 저에게 가장 적합한 문제는 다음과 같습니다.

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

기본값으로 UTC 타임스탬프가 필요하여 Daniel의 솔루션을 다음과 같이 수정했습니다.

    [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 튜토리얼은 이 멋진 블로그 게시물을 참조하십시오.

방법이 있어요.다음 클래스를 추가합니다.

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;
        }
    }
}

DefaultDateTime입니다.Extensions.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를 사용합니다.유효성 검사 속성에 입력할 값은 "Now"와 같은 것으로, Activator로 생성된 DateTime 인스턴스에서 런타임에 렌더링됩니다.소스 코드는 이 스레드에서 영감을 받았습니다. https://code.msdn.microsoft.com/A-flexible-Default-Value-11c2db19.ValidationAttribute 대신 DefaultValueAttribute로 클래스를 상속하도록 변경했습니다.

C# 버전 6에서는 기본값을 제공할 수 있습니다.

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

용용을 사용합니다.EntityTypeConfiguration 나는 다음과 같이 이해해요: , 는는게이 :: :: :: :: , : , , , , , 。

public class UserMap : IEntityTypeConfiguration<User>
{
    public void Configure(EntityTypeBuilder<User> builder)
    {
        //throw new NotImplementedException();
        builder.Property(u => u.Id).ValueGeneratedOnAdd();
        builder.Property(u => u.Name).IsRequired().HasMaxLength(100);
        builder.HasIndex(u => u.Email).IsUnique();
        builder.Property(u => u.Status).IsRequired();
        builder.Property(u => u.Password).IsRequired();
        builder.Property(u => u.Registration).HasDefaultValueSql("getdate()");

        builder.HasMany(u => u.DrawUser).WithOne(u => u.User);

        builder.ToTable("User");
    }
}

Fluent API를 사용하여 컨텍스트 클래스의 OnModelCreating 함수에 다음을 추가합니다.

 builder.Property(u => u.CreatedAt).ValueGeneratedOnAdd();
 builder.Property(u => u.UpdatedAt).ValueGeneratedOnAddOrUpdate();

다른 유형 구성 클래스를 사용하고 있습니다.기능을 제대로 수행했다면 다음과 같습니다.

builder.Enitity<User>().Property(u => u.CreatedAt).ValueGeneratedOnAdd();
public DateTime DateCreated
{
   get
   {
      return (this.dateCreated == default(DateTime))
         ? this.dateCreated = DateTime.Now
         : this.dateCreated;
   }

   set { this.dateCreated = value; }
}
private DateTime dateCreated = default(DateTime);

현재 이 문제를 해결하는 방법은 SQL 또는 EntityFramework에 Linkq를 사용하는 모델에 따라 달라집니다.

L2S에서 다음을 추가할 수 있습니다.

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

        ExecuteDynamicInsert(instance);
    }
}

EF는 좀 더 복잡합니다. EF 비즈니스 논리에 대한 자세한 내용은 http://msdn.microsoft.com/en-us/library/cc716714.aspx을 참조하십시오.

이 게시물이 조금 오래된 건 알지만, A가 도움이 될 만한 제안이 있습니다.

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:을 클릭합니다.

Public Enum EInitialValue
   DateTime_Now
   DateTime_Min
   DateTime_Max
End Enum

다음을 사용하여 할 수 있을 것 같습니다.StoreGeneratedPattern = Identity(모델 디자이너 속성 창에서 설정)을 클릭합니다.

그렇게 할 줄은 몰랐지만, 알아보려고 하는 동안 일부 날짜 열이 이미 기본값으로 설정되어 있다는 것을 알게 되었습니다.CURRENT_TIMESTAMP()그렇지 않은 사람도 있었어요모델을 확인해보니 이름 외에 두 열 사이의 유일한 차이점은 기본값을 얻는 열에는 다음 값이 있다는 것입니다.StoreGeneratedPattern로 설정합니다.Identity.

그렇게 될 줄은 몰랐는데 인상착의를 보니 말이 되네요

삽입 및 업데이트 작업 중에 데이터베이스의 해당 열이 자동으로 생성되는지 여부를 결정합니다.

또한 이렇게 하면 데이터베이스 열의 기본값이 "now"로 설정되지만 실제로 속성을 다음과 같이 설정하지는 않을 수 있습니다.DateTime.NowPOCO에서요이미 모든 날짜 열을 다음과 같이 설정하는 사용자 정의된 .tt 파일이 있기 때문에 이 문제는 문제가 되지 않았습니다.DateTime.Now자동으로(특히 ReSharper가 있고 구문 강조 표시 플러그인이 있는 경우 .tt 파일을 직접 수정하는 것은 어렵지 않습니다.(새로운 버전의 VS는 이미 .tt 파일을 강조 표시할 수 있습니다. 확실하지 않습니다.)

문제는 데이터베이스 열에 기본값을 설정하여 해당 열을 생략한 기존 쿼리가 계속 작동하도록 하려면 어떻게 해야 합니까?그리고 위의 설정이 작동했습니다.

아직 테스트하지 않았지만 이 설정을 통해 사용자 자신의 명시적 값을 설정하는 데 방해가 될 수도 있습니다.(처음에는 EF6 Database First가 모델을 이렇게 작성했기 때문에 이 사실을 알게 되었습니다.)

아래는 에서 작동합니다.NET 5.0입니다.

        private DateTime _DateCreated= DateTime.Now;
        public DateTime DateCreated
        {
            get
            {
                return this._DateCreated;
            }

            set { this._DateCreated = value; }
        }

DatabaseGenerated 속성 사용을 고려할 수도 있습니다. 예

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public DateTime DateCreated { get; set; }

https://learn.microsoft.com/en-us/ef/core/modeling/generated-properties?tabs=data-annotations

저도 이 방법을 원했고 이 솔루션을 생각해 냈습니다(날짜 부분만 사용하고 있습니다. 기본 시간은 PropertyGrid 기본값으로 의미가 없습니다).

public class DefaultDateAttribute : DefaultValueAttribute {
  public DefaultDateAttribute(short yearoffset)
    : base(DateTime.Now.AddYears(yearoffset).Date) {
  }
}

이렇게 하면 DateTime 속성에 추가할 수 있는 새 속성이 생성됩니다.예를 들어, 기본값이 DateTime인 경우입니다.지금이요.날짜:

[DefaultDate(0)]

언급URL : https://stackoverflow.com/questions/691035/setting-the-default-value-of-a-datetime-property-to-datetime-now-inside-the-syst 입니다.

반응형