Programing

datetime2 데이터 유형을 datetime 데이터 유형으로 변환하면 범위를 벗어난 값

lottogame 2020. 3. 1. 15:36
반응형

datetime2 데이터 유형을 datetime 데이터 유형으로 변환하면 범위를 벗어난 값


5 개의 열이있는 데이터 테이블이 있는데 행은 데이터로 채워지고 트랜잭션을 통해 데이터베이스에 저장됩니다.

저장하는 동안 오류가 반환됩니다.

datetime2 데이터 유형을 datetime 데이터 유형으로 변환하면 범위를 벗어난 값이 발생했습니다.

내 데이터 테이블에는 유형이 DateTime2있고 내 데이터베이스가 있음을 나타냅니다 DateTime. 그건 잘못이야

날짜 열은 다음 DateTime과 같이 설정됩니다 .

new DataColumn("myDate", Type.GetType("System.DateTime"))

질문

이것을 코드로 해결할 수 있습니까? 아니면 데이터베이스 수준에서 무언가를 변경해야합니까?


칼럼에 어떤 종류의 날짜가 있습니까?

그것들 모두 유형의 범위에 맞습니까?


제쳐두고, 생성자 를 위해 Type객체 를 얻는 올바른 방법 DataColumntypeof키워드입니다.

따라서 열을 만들려면 다음을 작성해야합니다.

new DataColumn("myDate", typeof(DateTime))

필드가 NULL 값을 허용하지 않을 때 DateTime 필드에 값을 지정하지 않으면 이런 일이 발생할 수 있습니다 .

그것은 나를 위해 그것을 고쳤다!


DATETIME.NET에서 모두 DATETIME2매핑 System.DateTime-실제로는 .NET 유형과 동일하므로 실제로 "변환"을 수행 할 수 없습니다.

MSDN 문서 페이지를 참조하십시오 : http://msdn.microsoft.com/en-us/library/bb675168.aspx

이 두 가지에 대해 " SqlDbType" 에는 두 가지 값 이 있습니다. DataColumn정의 에서 값을 지정할 수 있습니까?

그러나 SQL Server에서 지원되는 날짜 범위는 상당히 다릅니다.

DATETIME1753/1/1 ~ "영원"(9999/12/31)을 DATETIME2지원하고 0001/1/1 ~ 영원 지원합니다.

따라서 실제로해야 할 일은 날짜의 연도를 확인하는 것입니다 .1753 이전 인 경우 DATETIMESQL Server 열이 처리 할 수 ​​있도록 1753 이후로 변경해야 합니다.

마크


내 SQL Server 2008 데이터베이스에서 DateTime열을 nullable로 표시하지 않지만 GetDate()함수를 기본값으로 표시했습니다. EF4를 사용하여 새 객체를 삽입 할 때 객체에 DateTime 속성을 명시 적으로 전달하지 않았기 때문에이 오류가 발생했습니다. SQL 함수가 날짜를 처리 할 것으로 예상했지만 그렇지 않았습니다. 내 솔루션은 데이터베이스에 의존하지 않고 코드에서 날짜 값을 보내서 생성하는 것이 었습니다.

obj.DateProperty = DateTime.now; // C#

나를 위해 그것은 날짜 시간 때문이었다 ..

01/01/0001 00:00:00

이 경우에는 FirstYearRegistered 코드를 예로 사용하여 EF DateTime Object에 null을 할당하려고합니다.

DateTime FirstYearRegistered = Convert.ToDateTime(Collection["FirstYearRegistered"]);
if (FirstYearRegistered != DateTime.MinValue)
{
    vehicleData.DateFirstReg = FirstYearRegistered;
}  

때때로 EF는 이것이 계산 된 열 이나 트리거를 처리하는지 알지 못합니다 . 의도적으로 이러한 작업은 삽입 후 EF 외부의 값을 설정합니다.

수정은 속성 에서 해당 열의 ComputedEF 로 지정하는 것 입니다 .edmxStoreGeneratedPattern

나를 위해 열에 현재 날짜와 시간을 삽입 한 트리거가 있었을 때였습니다. 세 번째 섹션의 아래를 참조하십시오.


해결 단계

Visual Studio에서 Model Browser페이지를 연 Model다음 Entity Types->

  1. 엔티티 및 날짜 시간 특성을 선택하십시오.
  2. 고르다 StoreGeneratedPattern
  3. 로 설정 Computed

EF 모델 브라우저 모델 엔티티 유형 대화 상자


이 상황에서 다른 대답은 임시 해결책입니다. 열의 목적 상 레코드를 만들 때 지정된 시간 / 날짜를 지정하는 것입니다. 이는 올바른 시간을 추가하기 위해 트리거를 실행하는 SQL의 작업입니다. 이 SQL 트리거와 같은 :

DEFAULT (GETDATE()) FOR [DateCreated].


이것은 나를 미치게했다. nullable 날짜 시간 ( DateTime?)을 사용하지 않으려 고했습니다 . SQL Server 2008 datetime2유형 을 사용할 수있는 옵션이 없었습니다.

modelBuilder.Entity<MyEntity>().Property(e => e.MyDateColumn).HasColumnType("datetime2");

나는 결국 다음을 선택했다.

public class MyDb : DbContext
{
    public override int SaveChanges()
    {
        UpdateDates();
        return base.SaveChanges();
    }

    private void UpdateDates()
    {
        foreach (var change in ChangeTracker.Entries<MyEntityBaseClass>())
        {
            var values = change.CurrentValues;
            foreach (var name in values.PropertyNames)
            {
                var value = values[name];
                if (value is DateTime)
                {
                    var date = (DateTime)value;
                    if (date < SqlDateTime.MinValue.Value)
                    {
                        values[name] = SqlDateTime.MinValue.Value;
                    }
                    else if (date > SqlDateTime.MaxValue.Value)
                    {
                        values[name] = SqlDateTime.MaxValue.Value;
                    }
                }
            }
        }
    }
}

나는 이것을 만나서 datetime 속성에 다음을 추가했습니다.

 [Column(TypeName = "datetime2")]
 public DateTime? NullableDateTimePropUtc { get; set; }

날짜 시간을 날짜 시간 필드로 전달하지 않으면 기본 날짜 {1/1/0001 12:00:00 AM}이 전달됩니다.

그러나이 날짜는 엔터티 프레임 작업과 호환되지 않으므로 datetime2 데이터 형식을 datetime 데이터 형식으로 변환하여 범위를 벗어난 값이 발생합니다.

그냥 default DateTime.now날짜 필드에 어떤 날짜를 통과하지 않는 경우.

movie.DateAdded = System.DateTime.Now

가장 쉬운 방법은 datetime 대신 datetime2를 사용하도록 데이터베이스를 변경하는 것입니다. 호환성은 훌륭하게 작동하며 오류가 발생하지 않습니다.

여전히 많은 테스트를 원할 것입니다 ...

오류는 아마도 날짜를 0 년 또는 다른 것으로 설정하려고하기 때문일 수 있습니다.하지만 모두 변경 사항을 제어 할 수있는 위치에 따라 다릅니다.


나는이 게시물이 왜 다른 대답에 의해 설명 된 다음과 같은 오류가 계속 발생했는지 알아 내려고 노력했습니다.

datetime2 데이터 유형을 datetime 데이터 유형으로 변환하면 범위를 벗어난 값이 발생했습니다.

널 입력 가능 DateTime 오브젝트를 사용하십시오.
공개 DateTime? PurchaseDate {get; 세트; }

엔티티 프레임 워크를 사용하는 경우 edmx 파일에서 널 입력 가능 특성을 True로 설정하십시오.

edmx 파일의 널 입력 가능 특성을 ** 참 **으로 설정하십시오.


으로 andyuk가 이미 지적 아웃이, 이것은 경우에 발생할 수 NULL의 값이 아닌 널 (NULL)에 지정된 날짜 시간 필드. DateTimeDateTime으로 변경 하시겠습니까? 또는 Nullable < DateTime >입니다. 종속성 속성을 사용하는 경우 종속성 속성의 유형도 nullable DateTime 유형인지 확인해야합니다.

다음은 불완전한 DateTime 에서 DateTime 까지 의 실제 예입니다 . 이상한 행동을 일으키는 유형 조정

여기에 이미지 설명을 입력하십시오


Entity Framework 4는 datetime2 데이터 형식과 함께 작동하므로 db에서 해당 필드는 SQL Server 2008의 datetime2 여야합니다.

솔루션을 달성하기 위해 두 가지 방법이 있습니다.

  1. Entity Framwork 4에서 날짜 시간 데이터 유형을 사용하려면 edmx 파일의 ProviderManifestToken을 "2005"로 전환해야합니다.
  2. 해당 필드를 널 허용으로 설정하면 (널 (NULL) 가능으로 변환) EF는 자동으로 날짜 오브젝트를 날짜 시간으로 사용합니다.

@ sky-dev 구현을 기반으로 기본 클래스를 만들었습니다. 따라서 여러 컨텍스트 및 엔터티에 쉽게 적용 할 수 있습니다.

public abstract class BaseDbContext<TEntity> : DbContext where TEntity : class
{
    public BaseDbContext(string connectionString)
        : base(connectionString)
    {
    }
    public override int SaveChanges()
    {

        UpdateDates();
        return base.SaveChanges();
    }

    private void UpdateDates()
    {
        foreach (var change in ChangeTracker.Entries<TEntity>())
        {
            var values = change.CurrentValues;
            foreach (var name in values.PropertyNames)
            {
                var value = values[name];
                if (value is DateTime)
                {
                    var date = (DateTime)value;
                    if (date < SqlDateTime.MinValue.Value)
                    {
                        values[name] = SqlDateTime.MinValue.Value;
                    }
                    else if (date > SqlDateTime.MaxValue.Value)
                    {
                        values[name] = SqlDateTime.MaxValue.Value;
                    }
                }
            }
        }
    }
}

용법:

public class MyContext: BaseDbContext<MyEntities>
{

    /// <summary>
    /// Initializes a new instance of the <see cref="MyContext"/> class.
    /// </summary>
    public MyContext()
        : base("name=MyConnectionString")
    {
    }
    /// <summary>
    /// Initializes a new instance of the <see cref="MyContext"/> class.
    /// </summary>
    /// <param name="connectionString">The connection string.</param>
    public MyContext(string connectionString)
        : base(connectionString)
    {
    }

     //DBcontext class body here (methods, overrides, etc.)
 }

내 경우에는 Datetime을 Datetime으로 캐스팅 하고이 오류가 발생했습니다. Datetime은 1753에 고정되어 있지만 Date는 "더 프로그래머 지향"최소 01/01/0001입니다.

이 부분을 데이터 수집 오류와 결합하면 예외가 발생합니다!


때로는 서버가 아닌 개발 시스템에서 잘 작동합니다. 내 경우에는 다음을 넣어야했습니다.

<globalization uiCulture="es" culture="es-CO" />

web.config 파일에서

머신 (서버)의 시간대는 맞았지만 (CO 로캘) 웹 앱은 그렇지 않았습니다. 이 설정이 완료되었으며 다시 정상적으로 작동했습니다.

물론 모든 날짜에는 가치가있었습니다.

:디


이 코드를 ASP.NET의 클래스에 추가하면 나에게 도움이되었습니다.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));
}

나는이 문제를 알고 있으며 당신도 모두해야합니다.

https://ko.wikipedia.org/wiki/Year_2038_problem

SQL에서는이 문제 (datetime2)를 피하기 위해 새로운 필드 유형이 작성되었습니다.

이 'Date'필드 유형은 DateTime .Net 클래스와 동일한 범위 값을 갖습니다. 모든 문제를 해결할 것이므로 데이터베이스 열 유형을 변경하는 것이 가장 좋습니다. 테이블 데이터에는 영향을 미치지 않습니다.


다음 두 가지를 확인하십시오. 1)이 필드에는 NULL 값이 없습니다. 예를 들면 다음과 같습니다.

 public DateTime MyDate { get; set; }

다음으로 교체하십시오.

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

2) 데이터베이스를 다시 새로 작성하십시오. 예를 들면 다음과 같습니다.

db=new MyDb();

1/1/1001과 같이 허용 된 dattime의 최소값을 lesathan으로 설정 한 날짜 열이 있습니다.

이 문제를 극복하기 위해 적절한 datetime 값을 ur 속성으로 설정하고 IsSpecified = true와 같은 다른 마법 속성을 설정할 수도 있습니다.

참고 URL : https://stackoverflow.com/questions/1331779/conversion-of-a-datetime2-data-type-to-a-datetime-data-type-results-out-of-range



반응형