Verwenden von SQL Server 2008 und SQL Server 2005 sowie Datum und Uhrzeit

118

Ich habe ein Entity-Framework-Modell für eine 2008-Datenbank erstellt. Gegen die Datenbank 2008 funktioniert alles in Ordnung. Wenn ich versuche, die Entität in einer 2005-Datenbank zu aktualisieren, wird dieser Fehler angezeigt.

Die verwendete Version von SQL Server unterstützt den Datentyp 'datetime2' nicht

Ich habe beim Erstellen der Datenbank keine 2008-Funktionen verwendet. Ich kann im Code keinen Verweis auf datetime2 finden. Und ja, die Spalte ist in der Datenbank als "Datum / Uhrzeit" definiert.

Monroecheeseman
quelle

Antworten:

189

Ein kurzer Blick auf Google zeigt mir, wie die Lösung aussieht .

Öffnen Sie Ihr EDMX in einem Datei-Editor (oder "Öffnen mit ..." in Visual Studio und wählen Sie XML-Editor). Oben finden Sie das Speichermodell mit dem Attribut ProviderManifestToken. Dies sollte den Wert 2008 haben. Ändern Sie dies auf 2005, kompilieren Sie neu und alles funktioniert.

HINWEIS: Sie müssen dies jedes Mal tun, wenn Sie das Modell aus der Datenbank aktualisieren.

Richard Harrison
quelle
2
Ich habe dies versehentlich abgelehnt, das aber aufgehoben, aber jetzt kann ich nicht das tun, was ich wirklich wollte, nämlich es abzustimmen! Vielen Dank, dass Sie das Problem gefunden haben. Wenn ich das richtig verstehe, ändert sich der Wert von 2005 auf 2008 aufgrund der Aktualisierung des Modells aus der Datenbank, in der es sich bei der Datenbank um eine SQL 2008-Datenbank handelt? In meiner Umgebung hat mein Entwicklercomputer SQL 2008, aber die Testumgebung hat 2005 (welche Produktion auch). Kann ich zu Recht davon ausgehen, dass dies bis zu unserer Migration auf 2008 so bleibt?
jamiebarrow
Ich setze dies im Allgemeinen auf 2005, die Produktionsdatenbank. Ich benutze 2008 für die Entwicklung. 2008 ist abwärtskompatibel, also keine Probleme. Auch dies muss nach einem Update / Generieren wieder geändert werden. Ich bestätige dies immer, wenn ich nach bitterer Erfahrung im EDMX einchecke.
Richard Harrison
Dieser Fix funktioniert nicht für mich? forums.asp.net/p/1770522/4838628.aspx/…
Welsh King
Wenn dies in LightSwitch geschieht, lesen Sie meinen Blog-Beitrag, in dem erläutert wird, wie das Problem in der lsml-Datei behoben wird (da in LS kein direkter Zugriff auf die edmx-Datei besteht): lightwitchcentral.net.au/Blog/tabid/83/EntryId/27/ …
Yann Duran
Es ist die einzige Lösung, aber Sie sollten sich bewusst sein, dass Sie dies jedes Mal tun müssen, wenn Sie den edmx ändern, da er sich selbst zurücksetzen wird
Dave Hogan
11

Schnellansicht der Linie:

<Schema Namespace="Foobar.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005" >
Jason
quelle
10

Dies ist sehr frustrierend und ich bin überrascht, dass MS beschlossen hat, es nicht zu machen, damit Sie auf eine bestimmte SQL-Version abzielen können. Um sicherzustellen, dass wir auf 2005 abzielen, habe ich eine einfache Konsolen-App geschrieben und sie in einem PreBuild-Schritt aufgerufen.

Der vorgefertigte Schritt sieht folgendermaßen aus:

$(SolutionDir)Artifacts\SetEdmxVer\SetEdmxSqlVersion $(ProjectDir)MyModel.edmx 2005

Der Code ist hier:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace SetEdmxSqlVersion
{
    class Program
    {
        static void Main(string[] args)
        {
            if (2 != args.Length)
            {
                Console.WriteLine("usage: SetEdmxSqlVersion <edmxFile> <sqlVer>");
                return;
            }
            string edmxFilename = args[0];
            string ver = args[1];
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(edmxFilename);

            XmlNamespaceManager mgr = new XmlNamespaceManager(xmlDoc.NameTable);
            mgr.AddNamespace("edmx", "http://schemas.microsoft.com/ado/2008/10/edmx");
            mgr.AddNamespace("ssdl", "http://schemas.microsoft.com/ado/2009/02/edm/ssdl");
            XmlNode node = xmlDoc.DocumentElement.SelectSingleNode("/edmx:Edmx/edmx:Runtime/edmx:StorageModels/ssdl:Schema", mgr);
            if (node == null)
            {
                Console.WriteLine("Could not find Schema node");
            }
            else
            {
                Console.WriteLine("Setting EDMX version to {0} in file {1}", ver, edmxFilename);
                node.Attributes["ProviderManifestToken"].Value = ver;
                xmlDoc.Save(edmxFilename);
            }
        }
    }
}
Vance Kessler
quelle
@Vance vielen Dank, perfekt. Ein wenig langsam, da ich drei edmx-Dateien habe, die ich ändern muss. Fügen Sie daher möglicherweise eine Lösungskonfiguration hinzu, um sie nach einer Bereitstellung wiederherzustellen, und entfernen Sie sie aus dem üblichen Build. Wird jetzt eine Antwort mit den Informationen zur Verwendung dieses praktischen Tools in einem BeforeBuild (oder AfterBuild) anstelle eines Pre-Builds veröffentlichen. Sehr geschätzt.
MemeDeveloper
3

Mit der oben genannten praktischen Konsolen-App von @ Vance habe ich Folgendes als BeforeBuild-Ereignis verwendet

<Target Name="BeforeBuild">
    <!--Check out BD.edmx, Another.edmx, all configs-->
    <Exec Command="$(SolutionDir)\Library\tf checkout /lock:none $(ProjectDir)Generation\DB.edmx" />
    <Exec Command="$(SolutionDir)\Library\tf checkout /lock:none $(ProjectDir)Generation\Another.edmx" />
    <!--Set to 2008 for Dev-->
    <Exec Condition=" '$(Configuration)' == 'DEV1' " Command="$(SolutionDir)Library\SetEdmxSqlVersion $(ProjectDir)Generation\DB.edmx 2008" />
    <Exec Condition=" '$(Configuration)' == 'DEV1' " Command="$(SolutionDir)Library\SetEdmxSqlVersion $(ProjectDir)Generation\Another.edmx 2008" />
    <Exec Condition=" '$(Configuration)' == 'DEV2' " Command="$(SolutionDir)Library\SetEdmxSqlVersion $(ProjectDir)Generation\DB.edmx 2008" />
    <Exec Condition=" '$(Configuration)' == 'DEV2' " Command="$(SolutionDir)Library\SetEdmxSqlVersion $(ProjectDir)Generation\Another.edmx 2008" />
    <!--Set to 2005 for Deployments-->
    <Exec Condition=" '$(Configuration)' == 'TEST' " Command="$(SolutionDir)Library\SetEdmxSqlVersion $(ProjectDir)Generation\DB.edmx 2005" />
    <Exec Condition=" '$(Configuration)' == 'TEST' " Command="$(SolutionDir)Library\SetEdmxSqlVersion $(ProjectDir)Generation\Another.edmx 2005" />
    <Exec Condition=" '$(Configuration)' == 'PRODUCTION' " Command="$(SolutionDir)Library\SetEdmxSqlVersion $(ProjectDir)Generation\DB.edmx 2005" />
    <Exec Condition=" '$(Configuration)' == 'PRODUCTION' " Command="$(SolutionDir)Library\SetEdmxSqlVersion $(ProjectDir)Generation\Another.edmx 2005" />
  </Target>

Dies ist sehr praktisch, da lästige Umschichtungen vermieden werden. Danke, dass du Vance geteilt hast.

Ich habe TF.exe zum Bibliothekslösungsordner hinzugefügt, und dies hilft, da ich jetzt die edmx-Dateien als Teil des Builds auschecken kann, bevor ich versuche, sie zu bearbeiten. Außerdem habe ich dies mit Bedingungen hinzugefügt, sodass es für Bereitstellungen auf dem Server auf 2005 und für die SLN-Konfigurationen des Dev-Computers auf 2008 zurückgesetzt wird. Um zu erwähnen, müssen Sie die tatsächlichen SetEdmxSqlVersion.exe- (und .pdb) -Dateien zum Bibliotheksordner hinzufügen (oder wo immer Sie diese Bits behalten möchten).

Vielen Dank @Vance. Wirklich ordentlich, enorm zeitsparend und hält meine Builds völlig automatisiert und schmerzfrei :)

MemeDeveloper
quelle
2

Hatte ein ähnliches Problem mit 2012 vs. 2008. Es kann mit einem BeforeBuild-Ereignis mit XmlPeek und XmlPoke gelöst werden:

   <Target Name="BeforeBuild">
      <XmlPeek XmlInputPath="$(ProjectDir)MyModel.edmx"
               Namespaces="&lt;Namespace Prefix='edmx' Uri='http://schemas.microsoft.com/ado/2009/11/edmx'/&gt;&lt;Namespace Prefix='ssdl' Uri='http://schemas.microsoft.com/ado/2009/11/edm/ssdl'/&gt;"
               Query="/edmx:Edmx/edmx:Runtime/edmx:StorageModels/ssdl:Schema/@ProviderManifestToken">
         <Output TaskParameter="Result" ItemName="TargetedSQLVersion" />
      </XmlPeek>

      <XmlPoke Condition="@(TargetedSQLVersion) != 2008"
               XmlInputPath="$(ProjectDir)MyModel.edmx"
               Namespaces="&lt;Namespace Prefix='edmx' Uri='http://schemas.microsoft.com/ado/2009/11/edmx'/&gt;&lt;Namespace Prefix='ssdl' Uri='http://schemas.microsoft.com/ado/2009/11/edm/ssdl'/&gt;"
               Query="/edmx:Edmx/edmx:Runtime/edmx:StorageModels/ssdl:Schema/@ProviderManifestToken"
               Value="2008">
      </XmlPoke>
   </Target>

Wenn Sie das automatische Ersetzen nicht mögen, können Sie die XmlPoke-Aufgabe einfach durch eine Fehleraufgabe ersetzen.

Edgar
quelle
Dies ist viel besser als die Verwendung einer externen ausführbaren Datei. Dadurch kann MSBuild alle Phantasien intern verarbeiten. Dies alles kann CallTargetabhängig von den Veröffentlichungs- / Erstellungskonfigurationen einfach über bedingte Zielaufgaben vor dem Erstellen verkettet werden . (EG ändert sich nur bei der Bereitstellung in einer SQL2005-Umgebung)
Zugelassen
1

Zum Wohle der Menschen , die das gleiche Problem auftritt , sondern verwenden Kodex zunächst Besuche meine Antwort hier darüber , wie die Änderungen ProviderManifestTokenin der Code - Erste. Es geht um eine Schaffung DbModelBuildermanuell und Leiten einer DbProviderInfoInstanz (mit dem entsprechenden Token) , wenn das Modell Builder des rufenden BuildMethode.

sinelaw
quelle
Ich denke, Type System Version=SQL Server 2005in Verbindungszeichenfolge gesetzt kann auch funktionieren
Code4j
0

Eine bessere Lösung für mich ist, anstatt die EDMX-Datei manuell zu bearbeiten, edmx nur im Entwurfsmodus und im Kontextmenü "Modell aus Datenbank aktualisieren ..." zu öffnen. Sie müssen natürlich auf die richtige SQL-Version zeigen, was auch immer dies für Sie ist.

Marek
quelle
1
Ich denke, dies ist das Problem von OP - er entwickelte sich gegen ein lokales SQL 2008, wurde dann aber für SQL 2005 bereitgestellt.
StuartLC
Dies funktioniert nur, wenn Sie keinen Zugriff auf eine SQL 2005-Instanz haben.
Darcy
1
Ein großer Nachteil ist, dass es sich um einen manuellen Schritt handelt und somit vergessen wird.
Jowen
0

Wir hatten diesen Fehler in SQL2005 v.3, wo wir ihn in SQL2005 v.4 nicht hatten.

Das Hinzufügen von SQL2005 zur Verbindungszeichenfolge hat unser spezifisches Problem behoben.

Wir haben noch nicht herausgefunden, warum und wollten den Code nicht ändern, um das oben gelöste Token bereitzustellen (Problem während der Bereitstellung).

Brian H.
quelle