it-swarm.com.de

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

Ich habe ein Entitätsrahmenmodell für eine Datenbank von 2008 erstellt. Alles funktioniert gegen die 2008 Datenbank. Wenn ich versuche, die Entität in einer 2005-Datenbank zu aktualisieren, erhalte ich diesen Fehler. 

Die verwendete Version von SQL Server unterstützt datetime2 nicht

Beim Erstellen der Datenbank habe ich insbesondere keine 2008-Funktionen verwendet. Ich kann im Code keinen Verweis auf datetime2 finden. Und ja, die Spalte ist in der Datenbank als "datetime" definiert. 

118
Monroecheeseman

Ein kurzer Google-Hinweis 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 und es hat ein Attribut ProviderManifestToken. Dies sollte den Wert 2008 haben. Ändern Sie das auf 2005, kompilieren Sie neu und alles funktioniert.

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

191

Schnellansicht der Linie:

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

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

Der Vorbauschritt 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);
            }
        }
    }
}
11
Vance Kessler

Mit der praktischen Konsolen-App von @ Vance oben 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>

Das ist super praktisch, da lästige Umschichtung vermieden wird. Danke für das Teilen von Vance.  

Ich habe TF.exe zum Bibliotheks-Lösungsordner hinzugefügt und dies ist hilfreich, da ich jetzt die edmx-Dateien auschecken kann, bevor ich versuche, sie als Teil des Builds zu bearbeiten. Ich habe dies auch mit Bedingungen hinzugefügt, so dass es für Implementierungen auf dem Server auf 2005 und für die Konfigurationen der Dev-Maschinen-Sln wieder auf 2008 gesetzt wird. Zu erwähnen ist auch, dass Sie die eigentlichen SetEdmxSqlVersion.exe (und .pdb) -Dateien zum Bibliotheksordner hinzufügen müssen (oder wo immer Sie diese Bits behalten möchten). 

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

4
MemeDeveloper

Zum Nutzen von Personen, die dasselbe Problem haben, aber Code First verwenden, überprüfen Sie meine Antwort hier , wie Sie die ProviderManifestToken in Code First ändern. Es umfasst das manuelle Erstellen einer DbModelBuilder und das Übergeben einer DbProviderInfo-Instanz (mit dem entsprechenden Token), wenn die Build-Methode des Modell-Builders aufgerufen wird.

2
sinelaw

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 den automatischen Austausch nicht mögen, können Sie die XmlPoke-Task einfach durch eine Error-Task ersetzen.

2
Edgar

Eine bessere Lösung ist für mich die manuelle Bearbeitung der EDMX-Datei. Öffnen Sie einfach edmx im Design-Modus und im Kontextmenü "Update Model from Database ..." . Sie müssen auf die richtige SQL-Version verweisen, was auch immer dafür ist Sie.

1
Marek

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

Durch Hinzufügen von SQL2005 zur Verbindungszeichenfolge wurde unser spezifisches Problem behoben.

Wir haben noch nicht den Grund dafür gefunden und wollten den Code nicht ändern, um das Token wie oben gelöst bereitzustellen (Problem während der Bereitstellung aufgetreten).

0
Brian H