Używam interfejsów API DbContext i Code First wprowadzonych w Entity Framework 4.1.
Model danych wykorzystuje podstawowe typy danych, takie jak string
i DateTime
. Jedyna adnotacja danych, której używam w niektórych przypadkach, to [Required]
, ale nie ma jej w żadnej z DateTime
właściwości. Przykład:
public virtual DateTime Start { get; set; }
DbContext podklasą jest również prosty i wygląda następująco:
public class EventsContext : DbContext
{
public DbSet<Event> Events { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Event>().ToTable("Events");
}
}
W initializer zestawy dat w modelu do wartości sensownych w obu tego roku lub w przyszłym roku.
Jednak po uruchomieniu inicjatora pojawia się ten błąd pod adresem context.SaveChanges()
:
Konwersja typu danych datetime2 na typ danych datetime spowodowała uzyskanie wartości spoza zakresu. Oświadczenie zostało zakończone.
W ogóle nie rozumiem, dlaczego tak się dzieje, ponieważ wszystko jest takie proste. Nie jestem też pewien, jak to naprawić, ponieważ nie ma pliku edmx do edycji.
Jakieś pomysły?
źródło
Odpowiedzi:
Musisz upewnić się, że Start jest większy lub równy SqlDateTime.MinValue (1 stycznia 1753) - domyślnie Start jest równy DateTime.MinValue (1 stycznia 0001).
źródło
Prosty. W kodzie najpierw ustaw typ DateTime na DateTime ?. Możesz więc pracować z typem DateTime dopuszczającym wartość null w bazie danych. Przykład jednostki:
źródło
W niektórych przypadkach
DateTime.MinValue
(lub równoważniedefault(DateTime)
) służy do wskazania nieznanej wartości.Ta prosta metoda rozszerzenia może pomóc w takich sytuacjach:
Stosowanie:
źródło
Możesz ustawić wartość pola na wartość null, jeśli odpowiada to Twoim konkretnym problemom związanym z modelowaniem. Data pusta nie zostanie wymuszona na datę, która nie mieści się w zakresie typu SQL DateTime, tak jak byłaby to wartość domyślna. Inną opcją jest jawne odwzorowanie na inny typ, na przykład za pomocą
źródło
Chociaż to pytanie jest dość stare i istnieją już świetne odpowiedzi, pomyślałem, że powinienem podać jeszcze jedno, które wyjaśnia 3 różne podejścia do rozwiązania tego problemu.
Podejście 1
Jawnie przypisz
DateTime
właściwośćpublic virtual DateTime Start { get; set; }
dodatetime2
w odpowiedniej kolumnie w tabeli. Ponieważ domyślnie EF zamapuje go nadatetime
.Można to zrobić za pomocą płynnego interfejsu API lub adnotacji danych.
Fluent API
W klasie DbContext nadpisanie
OnModelCreating
i skonfigurowanie właściwościStart
(ze względów wyjaśnienia jest to właściwość klasy EntityClass).Adnotacja danych
Podejście 2
Zainicjuj
Start
do wartości domyślnej w konstruktorze EntityClass.To jest dobre, jakby z jakiegoś powodu wartośćStart
nie została ustawiona przed zapisaniem jednostki do bazy danych start zawsze będzie miał wartość domyślną. Upewnij się, że wartość domyślna jest większa lub równa SqlDateTime.MinValue (od 1 stycznia 1753 do 31 grudnia 9999)Trzecie podejście
Make
Start
to be of type nullableDateTime
-note?
afterDateTime
-Więcej wyjaśnień znajdziesz w tym poście
źródło
Jeśli
DateTime
właściwości dopuszczają wartość null w bazie danych, pamiętaj, aby użyćDateTime?
dla skojarzonych właściwości obiektu lub EF zostanie przekazanyDateTime.MinValue
dla nieprzypisanych wartości, które są poza zakresem tego, co może obsłużyć typ daty / godziny SQL.źródło
Moim rozwiązaniem było przełączenie wszystkich kolumn z datą i godziną na datetime2 i użycie datetime2 dla wszystkich nowych kolumn. Innymi słowy, spraw, aby EF domyślnie używał datetime2. Dodaj to do metody OnModelCreating w swoim kontekście:
To dostanie wszystkie DateTime i DateTime? właściwości wszystkich Twoich podmiotów.
źródło
zainicjuj właściwość Start w konstruktorze
To zadziałało, gdy próbowałem dodać kilka nowych pól do tabeli użytkowników ASP .Net Identity Framework (AspNetUsers) przy użyciu Code First. Zaktualizowałem Class - ApplicationUser w IdentityModels.cs i dodałem pole lastLogin typu DateTime.
źródło
Opierając się na odpowiedzi użytkownika @ andygjp, lepiej jest zastąpić podstawę
Db.SaveChanges()
metodę i dodać funkcję nadpisującą dowolną datę, która nie mieści się między SqlDateTime.MinValue i SqlDateTime.MaxValue.Oto przykładowy kod
Zaczerpnięte z komentarza użytkownika @ sky-dev na https://stackoverflow.com/a/11297294/9158120
źródło
Miałem ten sam problem iw moim przypadku ustawiałem datę na new DateTime () zamiast DateTime.
źródło
W moim przypadku stało się tak, gdy użyłem encji, a tabela sql ma domyślną wartość datetime == getdate (). więc co zrobiłem, aby ustawić wartość w tym polu.
źródło
Używam Database First i kiedy pojawił się ten błąd, moim rozwiązaniem było wymuszenie ProviderManifestToken = "2005" w pliku edmx (dzięki czemu modele są zgodne z SQL Server 2005). Nie wiem, czy coś podobnego jest możliwe w przypadku Code First.
źródło
Jedna linia rozwiązuje ten problem:
Tak więc w moim kodzie dodałem:
Dodanie tego wiersza do podklasy DBContext przesłania void OnModelCreating sekcja powinno działać.
źródło
W moim przypadku po refaktoryzacji w EF6 moje testy zakończyły się niepowodzeniem z tym samym komunikatem o błędzie, co oryginalny plakat, ale moje rozwiązanie nie miało nic wspólnego z polami DateTime.
Po prostu brakowało mi wymaganego pola podczas tworzenia encji. Po dodaniu brakującego pola błąd zniknął. Mój podmiot ma dwie daty i godziny? pola, ale to nie był problem.
źródło