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


379

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

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

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

내 데이터 테이블에는 유형이 DateTime2있고 내 데이터베이스에는 DateTime; 그건 잘못이야

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

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

질문

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

답변:


60

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

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


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

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

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

3
내 데이터 열을 변경하고 지금 typeof를 사용했습니다 ... 추가로 문제를 찾았습니다. 날짜가 잘못되어 1 개의 데이터 행이있어서 오류가 발생했습니다.
Gerbrand

739

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

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


43
Entity Framework에서 null이 아닌 Created 열을 추가 한 경우 코드 값을 설정하지 않으면 EDMX를 업데이트하면 이러한 방식으로이 오류가 발생할 수 있습니다.
Brad Thomas

6
무엇이 당신을 위해 고쳤습니까? 이 오류는 getdate () 호출을 기본값으로하는 datetime 필드가있을 때 나타납니다.
user3046061

15
내 SQL 측에서 기본값 = getdate ()가 있기 때문에 NULL 인 경우 Entity Framework가 무시할 수없는 이유는 무엇입니까?
JoshYates1980

33
내가 생각하는 것은 EntityFramework가 0001 년인 DateTime.MinValue를보고 SQL 날짜 시간이 범위 값을 벗어난 것이므로이 값을 DateTime2 (년 0001 지원) 값으로 보내서 삽입 / 업데이트가 유효합니다. SQL에서이 DateTime2를 DateTime으로 변환하려고 시도하면 다른 값이 생성되므로 실패합니다. 두 가지 해결책은 다음과 같습니다. 1 모델에서 nullable 날짜 시간을 사용하거나 2. 컨텍스트 변경 사항을 저장하기 전에 모든 날짜 시간 값을 올바른 값으로 초기화합니다. 선택은 모델에서 날짜 시간의 의미에 따라 다릅니다.
기예르모 루피노

1
@GuillermoRuffino의 솔루션이 저에게 효과적이었습니다. 모든 필드를 검사하고 0001 년 항목을 찾으십시오.
Francesco B.

158

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 이후로 변경해야 합니다.

마크


7
이것은 내가 가진 문제를 설명합니다. 1753/1/1 이전의 실제 날짜를 처리해야하는 상황은 거의 없지만 오류가 발생할 수있는 기본값 0001/1/1을 얻는 상황이 많이 있습니다.
Hong

'datetime'데이터 형식에 'new DateTime ()'을 삽입하려고 할 때이 예외가 발생했음을 확인합니다.
George Onofrei

1
데이터베이스에 쓴 C # 코드에서 DateTime.MinValue의 기본값을 할당하려고했습니다. 이것은 내가 받고있는 오류를 설명합니다. +1
Mkalafut

내가 사용하는 엔티티 프레임 워크 코드 먼저 내가 날짜 시간 속성 모델을 사용합니다. DtInit = new System.DateTime(1492, 10, 12),실패합니다.
Kiquenet

이것은 실제 이유가 패치 뒤에 숨겨진 상황 중 하나입니다 ... +1
Eugenio Miró

41

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

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

2
기쁘다. EF 데이터 컨텍스트가 테이블에서 객체를 만들 때 필드에 기본값이 있음을 발견 할 수 있다고 생각하기 때문에 성가신 일입니다.
Graham

EF에 대해 많은 것을 생각합니다. POCO 자체 추적 엔터티를 사용하고 있으며 그러한 클러스터입니다. 코드 첫 번째 모델을 살펴보고, 그 말도 넌센스로 가득 찬 경우 linq에서 sql로 돌아가서 객체 매퍼를 사용하여 소품을 내 엔티티에 매핑하는 것에 대해 진지하게 생각하고 있습니다.

2
나는 2 주 전에 VS Live에서 EF Code First 데모를 보았는데, btw.
Graham

좋은 소식입니다. 우리는 곧 사무실에서 새 프로젝트를 시작하고 있으며 EF-CF와 dapper (SO에서 사용 / 유지 관리)로 분할하고 있습니다. WCF 서비스를 통해 사용되는 앱에서 더 좋을 것입니다.

1
안녕하세요, 오래된 의견입니다! 나는 EF Code-First로 시작하여 POCO에서 날짜 시간 멤버를로 정의해야한다는 것을 알았 Nullable<DateTime>습니다. 코드에서는 01/01/0000 대신 null을 그대로 둘 수 있습니다. EF to SQL이 INSERT 에서이 null을 무시하고 서버의 날짜를 사용하는 것을 알고 있다는 사실에 놀랐습니다 GetDate(). 웹 서버와 SQL 서버의 웹 서버.
Funka

34

나를 위해 날짜 시간이 되었기 때문에 ..

01/01/0001 00:00:00

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

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

ExcelDataReader를 사용 하여이 데이터를 구문 분석하고 유효하지 않은 텍스트가 입력되었을 때 01/01/0001을 반환합니다 (예 : .GetDateTime (columnIndex) 메서드 사용). MinValue와의 비교는 SQL에서 범위를 벗어난 예외를 방지하기 위해 트릭을 수행했습니다.
Tommy

22

이것은 나를 미치게했다. 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;
                    }
                }
            }
        }
    }
}

1
사용 [Column(TypeName = "datetime2")]?
Kiquenet

21

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

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

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


해결 단계

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

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

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


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

DEFAULT (GETDATE()) FOR [DateCreated].


GETDATE()내가 당시에 문자 그대로 사용한 것을 주목하십시오 . 그러나 최근에 SYSDATETIME()내가 믿고 있다고 생각하는 DateTime2 작업에 사용해야한다는 최근 의견이있었습니다 .
ΩmegaMan

10

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

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

1
using System.ComponentModel.DataAnnotations.Schema; 필요
Kiquenet

9

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

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

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

movie.DateAdded = System.DateTime.Now

'DateTime.Now'를 기본값으로 전달하는 것은 정확하지 않으며 오해의 소지가 있습니다.
Bartosz

6

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

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

오류는 아마도 날짜를 0 년 또는 다른 것으로 설정하려고하기 때문일 수 있습니다.


4

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

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

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

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

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


3

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

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

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


2

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

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

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

1
데이터베이스 모델 (POCO 클래스)에 대한 두 번째 요점을 골라 필드를 nullable 유형으로 설정하는 방법이 궁금합니다. 궁금한 사람이있는 경우 날짜 유형 뒤에 물음표 (?)를 추가하면됩니다. 예를 들어 공개 DateTime? StartTime {get; 세트; } 이렇게하면 문제가 해결되었습니다. 내가해야 할 또 다른 것은 TimeSpan 캐스트를 두 줄의 nullable DateTime 값을 서로 빼는 코드 줄 주위에 두는 것입니다. 예를 들어 var timeTaken = (TimeSpan) (endTime-startTime);
Ciaran Gallagher

1

@ 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.)
 }

1

모델 클래스의 속성에 아래 언급 된 속성을 추가하십시오.

Attribute = [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
Reference = System.ComponentModel.DataAnnotations.Schema

처음에는이 속성을 추가하는 것을 잊었습니다. 내 데이터베이스에서 제약 조건은 다음과 같이 생성되었습니다.

ALTER TABLE [dbo].[TableName] ADD DEFAULT (getdate()) FOR [ColumnName]

이 속성을 추가하고 내 db를 업데이트 한 다음

ALTER TABLE [dbo].[TableName] ADD CONSTRAINT [DF_dbo.TableName_ColumnName] DEFAULT (getdate()) FOR [ColumnName]

[DatabaseGenerated (DatabaseGeneratedOption.Computed)]
Ajith Chandran


0

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

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

web.config 파일에서

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

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

:디


0

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

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

0

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

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

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

이 'Date'필드 유형은 DateTime .Net 클래스와 동일한 범위 값을 갖습니다. 모든 문제를 해결할 것이므로 데이터베이스 열 유형을 변경하는 것이 최선의 방법이라고 생각합니다 (테이블 데이터에는 영향을 미치지 않습니다).


0

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

 public DateTime MyDate { get; set; }

다음으로 교체하십시오.

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

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

db=new MyDb();

값이 DateTime.Now가되지 않게하려면 어떻게합니까?
Savage

원하지 않는 경우 : DateTime.Now. 당신은 사용할 수 있습니다 : 새 날짜 시간을 (..., ..., ...)
RainyTears

0

상속 된 날짜 / 시간 속성 문제

이 오류 메시지는 삽입 할 수없는 날짜 필드에 삽입 / 업데이트 시간에 null 값이있는 경우 종종 표시됩니다. 하나의 원인은 상속 일 수 있습니다.

날짜가 기본 클래스에서 상속되고 매핑을하지 않으면 EF가 값을 읽지 않습니다.

자세한 내용은 https://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-3-table-per-concrete-type-tpc-and- 전략 선택 지침


0

ASP.Net MVC를 사용하여 페이지를 편집하려고 할 때이 오류가 발생했습니다. DateCreated 속성이 범위를 벗어 났지만 데이터베이스를 만들지 만 업데이트하는 동안 문제가 없었습니다!

당신이 원하지 않는 경우 DateTime속성은 null 허용하고 할 값이 SQL 날짜 시간 범위 내에 있는지 확인하지 (그리고 @Html.HiddenFor도움이되지 않습니다!), 간단하게 추가 static DateTime관련 클래스 (컨트롤러) 내부 필드를하고 그것을 때 값을 제공 GET이 작동 중이며 POST가 수행 중일 때 사용하십시오.

public class PagesController : Controller
{
    static DateTime dateTimeField;
    UnitOfWork db = new UnitOfWork();

    // GET:
    public ActionResult Edit(int? id)
    {
        Page page = db.pageRepository.GetById(id);
        dateTimeField = page.DateCreated;
        return View(page);
    }

    // POST: 
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(Page page)
    {
        page.DateCreated = dateTimeField;
        db.pageRepository.Update(page);
        db.Save();
        return RedirectToAction("Index");

    }
}

0

간단한 콘솔 앱 프로젝트 에서이 문제가 발생했으며 빠른 해결책은이 방법을 실행하여 가능한 모든 datetime2 날짜를 nullable datetime으로 변환하는 것입니다.

static DateTime? ParseDateTime2(DateTime? date)
    {
        if (date == null || date.ToString() == "1/1/0001 12:00:00 AM")
        {
            return null;
        }
        else
        {
            return date;
        }
    }

이것은 완전히 포괄적 인 방법은 아니지만 내 요구에 효과적이며 다른 사람들을 도울 것입니다!


0

DB에서 req 형식을 확인하십시오. 예를 들어 내 DB에는 기본값 또는 바인딩이 있습니다.(((1)/(1))/(1900))

System.DateTime MyDate = new System.DateTime( 1900 ,1, 1);

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


-1

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

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.