Entity Framework 7 schlägt fehl, datetime einzufügen

debian entity-framework-core mono sql-server windows

Frage

Ich benutze EntityFramework 7, beta7 und habe die folgende Entität:

C #

public class Log
{
    [Column(TypeName ="datetime")]
    public DateTime Date { get; set; }
    ...
}

SQL

CREATE TABLE [dbo].[Logs] (
    [Date] [datetime] NOT NULL,
    ...
)

Und ich führe folgendes aus:

db.Logs.Add(new Log { Date = DateTime.UtcNow });
db.SaveChanges();

Dies ist unter Windows erfolgreich, schlägt aber unter Mono auf Debian fehl. Gleicher SQL Server / Datenbank. Das generierte SQL ist unten. Beachten Sie den Unterschied von Typ und Wert für @p1 :

Windows

exec sp_executesql N'SET NOCOUNT OFF;
INSERT INTO [Logs] ([Browser], [Date], [Exception], [HostAddress], [Level], [Logger], [Message], [Thread], [Url], [Username])
OUTPUT INSERTED.[Id]
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9);
',N'@p0 nvarchar(max) ,@p1 datetime2(7),@p2 nvarchar(max) ,@p3 nvarchar(max) ,@p4 nvarchar(4000),@p5 nvarchar(4000),@p6 nvarchar(4000),@p7 nvarchar(4000),@p8 nvarchar(max) ,@p9 nvarchar(max) ',@p0=NULL,@p1='2015-09-28 23:02:26.0367851',@p2=NULL,@p3=NULL,@p4=N'INFO',@p5=N'Fanatics.ConsoleApp.Program',@p6=N'Console app test',@p7=N'0',@p8=NULL,@p9=NULL
go

Linux

exec sp_executesql N'SET NOCOUNT OFF;
INSERT INTO [Logs] ([Browser], [Date], [Exception], [HostAddress], [Level], [Logger], [Message], [Thread], [Url], [Username])
OUTPUT INSERTED.[Id]
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9);
',N'@p0 nvarchar(4000), @p1 char(27), @p2 nvarchar(4000), @p3 nvarchar(4000), @p4 nvarchar(4000), @p5 nvarchar(4000), @p6 nvarchar(4000), @p7 nvarchar(4000), @p8 nvarchar(4000), @p9 nvarchar(4000)',@p0=NULL,@p1='2015-09-28T23:03:21.5561720',@p2=NULL,@p3=NULL,@p4=N'INFO',@p5=N'Fanatics.ConsoleApp.Program',@p6=N'Console app test',@p7=N'0',@p8=NULL,@p9=NULL
go

Der Fehler unter Linux ist:

Beim Konvertieren von Datum und / oder Uhrzeit aus der Zeichenfolge ist die Konvertierung fehlgeschlagen.

Fragen

  1. Warum generiert Windows ein datetime2 wenn der Typ explizit auf datetime ?
  2. Die Linux-Version generiert ungültiges SQL, daher der Fehler. Wie kann ich datetime Werte auf Mono / Linux einfügen?

Akzeptierte Antwort

  1. .NET DateTime-Typ hat einen größeren Bereich als der "datetime" -Typ von SQL Server. Tatsächlich hat .NET DateTime den gleichen Bereich wie der Typ "datetime2" von sql server. Deshalb verwendet Entity Framework bei der Konvertierung von DateTime in sql date (wie in Ihrem Beispiel) überall datetime2 (wenn möglich). Der Typ der Tabellenspalte spielt in diesem Fall keine Rolle. Sie können diese Besprechungsnotizen für das Design lesen , in denen das EF-Team Probleme mit datetime und datetime2 erörtert und beschließt, dies so zu lassen (und die Gründe dafür).

  2. Mono verwendet TDS um mit sql server zu arbeiten (basierend auf FreeTDS , und es verwendet eine ziemlich veraltete Version. Diese Version hat keine Ahnung vom Typ "datetime2" von sql server, also anstatt auf eine neue Version von TDS zu aktualisieren (vielleicht ist das zu viel) arbeiten für jetzt), Art von Hack wurde implementiert, datetime2 von \ to string. Jetzt hat datetime2 eine höhere Genauigkeit als datetime, also beim Konvertieren von datetime2 in string und dann das Konvertieren dieser Zeichenfolge in datetime (was implizit getan wird) verursacht den Fehler Sie see. Das ist leicht zu überprüfen:

    select cast('2015-09-28T23:03:21.5561720' as datetime2) -- < all fine
    select cast('2015-09-28T23:03:21.5561720' as datetime) -- < error from your question
    

    Sie können ein bisschen mehr darüber lesen Sie hier .

Sie könnten fragen, ob Sie EF mit SQL Server auf Mono verwenden können. Nun, Sie können Abhilfe schaffen, indem Sie in Ihrem EF-Modell ProviderManifestToken auf 2005 setzen. Dies macht EF-Sache mit SQL Server 2005 funktioniert, und es wird nicht überall datetime2 verwenden. Aber du wirst andere Typen verlieren, die nach dem SQL Server 2005 offensichtlich hinzugefügt wurden, ganz zu schweigen davon, dass dreckiger Hack ist.

Als eine Randnotiz - machen Sie keine ernsthafte Entwicklung auf Mono mit SQL Server. Sql-Server-Anbieter in Mono ist voller Bugs und Bug oben ist einer der unschuldigsten. Es gibt Probleme mit NULL-Werten, Probleme mit dem Verbindungspool (dieser ist sehr ernst - wenn Sie bei Verbindungspool-Verbindung eine Zeitüberschreitung haben - wird diese Verbindung für die gesamte Lebensdauer unterbrochen und ALLE Abfragen dieser Verbindung werden fehlschlagen. Hack - Verbindung aus Verbindung entfernen Pool, wenn Ihre Anfrage abgelaufen ist), etc. Die meisten dieser Fehler sind seit Jahren bekannt und nicht behoben. Wenn Sie die Wahl haben - benutzen Sie einfach postgresql, es ist kostenlos, gut, und ich hatte keine Probleme damit auf Mono.



Related

Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum