Utilisation de SQL Server 2008 et SQL Server 2005 et date / heure

118

J'ai construit un modèle de cadre d'entité sur une base de données de 2008. Tout fonctionne bien avec la base de données 2008. Lorsque j'essaye de mettre à jour l'entité sur une base de données 2005, j'obtiens cette erreur.

La version de SQL Server utilisée ne prend pas en charge le type de données 'datetime2

Je n'ai spécifiquement utilisé aucune fonctionnalité de 2008 lorsque j'ai créé la base de données. Je ne trouve aucune référence à datetime2 dans le code. Et, oui, la colonne est définie comme "datetime" dans la base de données.

Monroecheeseman
la source

Réponses:

189

Un rapide google me montre à quoi ressemble la solution .

Ouvrez votre EDMX dans un éditeur de fichiers (ou «ouvrir avec…» dans Visual Studio et sélectionnez XML Editor). En haut, vous trouverez le modèle de stockage et il a un attribut ProviderManifestToken. Cela devrait avoir la valeur 2008. Changez cela en 2005, recompilez et tout fonctionne.

REMARQUE: vous devrez le faire chaque fois que vous mettez à jour le modèle à partir de la base de données.

Richard Harrison
la source
2
J'ai voté contre cela par erreur, annulé cela, mais maintenant je ne peux pas faire ce que je voulais vraiment faire, c'est voter! Merci d'avoir trouvé le problème. Si je comprends bien, la valeur change-t-elle de 2005 à 2008 en raison de la mise à jour du modèle à partir de la base de données, où la base de données est une base de données SQL 2008? Dans mon environnement, ma machine de développement a SQL 2008, mais l'environnement de test a 2005 (ce que la production a aussi). Jusqu'à ce que nous migrions vers 2008, ai-je raison de supposer que cela continuera à se produire?
jamiebarrow
Je règle généralement ceci sur 2005, qui est la base de données de production; J'utilise 2008 pour le développement. 2008 est rétrocompatible donc pas de problèmes. Cela doit également être modifié après une mise à jour / génération. Je valide toujours cela lors de l'enregistrement dans l'EDMX après une expérience amère.
Richard Harrison
ce correctif ne fonctionne pas pour moi ?? forums.asp.net/p/1770522/4838628.aspx/…
Welsh King
Si cela se produit dans LightSwitch, consultez mon article de blog qui explique comment le corriger dans le fichier lsml (car il n'y a pas d'accès direct au fichier edmx dans LS): lightswitchcentral.net.au/Blog/tabid/83/EntryId/27/ …
Yann Duran
C'est la seule solution, mais vous devez savoir que vous devez le faire chaque fois que vous modifiez l'edmx car il se rétablira
Dave Hogan
11

Vue rapide de la ligne:

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

C'est très frustrant et je suis surpris que MS ait décidé de ne pas le faire pour que vous puissiez cibler une version SQL donnée. Pour être sûr que nous visons 2005, j'ai écrit une application console simple et l'ai appelée dans une étape PreBuild.

L'étape de pré-construction ressemble à ceci:

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

Le code est ici:

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
la source
@Vance merci beaucoup, parfait. Un peu lent, car j'ai trois fichiers edmx que je dois modifier, je pourrais donc ajouter une configuration de solution juste pour revenir après un déploiement et la supprimer de la version habituelle. Publiera une réponse maintenant avec les informations sur l'utilisation de cet outil pratique dans un BeforeBuild (ou AfterBuild) au lieu d'une pré-construction. Très apprécié.
MemeDeveloper
3

En utilisant l'application console pratique de @ Vance ci-dessus, j'ai utilisé ce qui suit comme événement BeforeBuild

<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>

C'est très pratique, car cela évite un redéploiement ennuyeux. Merci d'avoir partagé Vance.

J'ai ajouté TF.exe au dossier de solution de bibliothèque et cela aide, car je peux maintenant vérifier les fichiers edmx avant d'essayer de les modifier, dans le cadre de la construction. J'ai également ajouté ceci avec des conditions, de sorte qu'il se règle en 2005 pour les déploiements sur le serveur et en 2008 pour les configurations de sln de machine de développement. Pour mentionner également, vous devez ajouter le (s) fichier (s) SetEdmxSqlVersion.exe (et .pdb) au dossier Bibliothèque (ou à tout autre endroit où vous souhaitez conserver ces bits).

Merci beaucoup @Vance. Vraiment soigné, gain de temps énorme et garde mes constructions totalement automatisées et sans douleur :)

MemeDeveloper
la source
2

J'ai eu un problème similaire avec 2012 par rapport à 2008. Il peut être résolu avec un événement BeforeBuild en utilisant XmlPeek et XmlPoke:

   <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>

Si vous n'aimez pas le remplacement automatisé, vous pouvez simplement remplacer la tâche XmlPoke par une tâche d'erreur.

Edgar
la source
C'est bien mieux que d'utiliser un exécutable externe, cela permet à MSBuild de gérer toute la fantaisie en interne. Tout cela peut être facilement enchaîné via CallTargetdes tâches cibles pré-build conditionnelles en fonction des configurations de publication / build. (EG ne change que lors du déploiement dans un environnement sql2005)
admalledd
1

Pour le bénéfice des personnes qui rencontrent le même problème mais qui utilisent Code First , consultez ma réponse ici sur la façon de changer le ProviderManifestTokendans Code First. Cela implique de créer une instance DbModelBuildermanuellement et de transmettre une DbProviderInfoinstance (avec le jeton approprié) lors de l'appel de la Buildméthode du générateur de modèle .

sinelaw
la source
Je pense que la Type System Version=SQL Server 2005chaîne de connexion peut également fonctionner
code4j
0

La meilleure solution pour moi est au lieu d'éditer manuellement le fichier EDMX, il suffit d'ouvrir edmx en mode conception et dans le menu contextuel "Mettre à jour le modèle à partir de la base de données ...". Vous devez bien sûr pointer vers la bonne version de SQL, quoi que ce soit pour vous.

Marek
la source
1
Je pense que c'est le problème d'OP - il a développé contre un SQL local 2008, mais ensuite déployé sur SQL 2005.
StuartLC
Cela fonctionne sauf si vous n'avez pas accès à une instance SQL 2005.
Darcy
1
Un énorme inconvénient est qu'il s'agit d'une étape manuelle et qu'elle sera donc oubliée.
Jowen
0

Nous avons eu cette erreur sur SQL2005 v.3, où nous ne l'avions pas sur SQL2005 v.4.

L'ajout de SQL2005 à la chaîne de connexion a résolu notre problème spécifique.

Nous n'avons pas encore identifié pourquoi et n'avons pas voulu modifier le code pour fournir le jeton comme résolu ci-dessus (problème manifesté lors du déploiement).

Brian H
la source