Utilizzo di SQL Server 2008 e SQL Server 2005 e data e ora


118

Ho costruito un modello di framework di entità su un database del 2008. Tutto funziona bene con il database del 2008. Quando provo ad aggiornare l'entità su un database 2005 ottengo questo errore.

La versione di SQL Server in uso non supporta il tipo di dati 'datetime2

In particolare, non ho utilizzato alcuna funzionalità del 2008 quando ho creato il database. Non riesco a trovare alcun riferimento a datetime2 nel codice. E, sì, la colonna è definita come "datetime" nel database.

Risposte:


189

Un rapido google mi indica quella che sembra la soluzione .

Apri il tuo EDMX in un editor di file (o "apri con ..." in Visual Studio e seleziona Editor XML). In alto troverai il modello di archiviazione e ha un attributo ProviderManifestToken. Questo dovrebbe avere il valore 2008. Modificalo al 2005, ricompila e tutto funziona.

NOTA: dovrai farlo ogni volta che aggiorni il modello dal database.


2
Ho votato per errore, annullato, ma ora non posso fare quello che volevo veramente fare, ovvero votare! Grazie per aver trovato il problema. Se ho capito bene, il valore cambia dal 2005 al 2008 a causa dell'aggiornamento del modello dal database, dove il database è un DB SQL 2008? Nel mio ambiente, la mia macchina sviluppatore ha SQL 2008, ma l'ambiente di test ha 2005 (che ha anche la produzione). Fino a quando non migreremo al 2008, ho ragione nel presumere che ciò continuerà a verificarsi?
jamiebarrow

In genere lo imposto a 2005, che è il database di produzione; Sto usando il 2008 per lo sviluppo. Il 2008 è compatibile con le versioni precedenti quindi nessun problema. Anche questo deve essere cambiato di nuovo dopo un aggiornamento / generazione. Lo convalido sempre quando effettuo il check-in nell'EDMX dopo un'amara esperienza.
Richard Harrison

questa correzione non funziona per me ?? forums.asp.net/p/1770522/4838628.aspx/…
Welsh King

Se ciò accade in LightSwitch, vedi il mio post sul blog che spiega come risolverlo nel file lsml (poiché non c'è accesso diretto al file edmx in LS): lightswitchcentral.net.au/Blog/tabid/83/EntryId/27/ ...
Yann Duran

È l'unica soluzione, ma dovresti essere consapevole che devi farlo ogni volta che modifichi l'edmx poiché si ripristinerà da solo
Dave Hogan

11

Visualizzazione rapida della linea:

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

10

Questo è molto frustrante e sono sorpreso che MS abbia deciso di non farlo in modo da poter scegliere come target una data versione di SQL. Per assicurarmi di puntare al 2005, ho scritto una semplice app per console e l'ho chiamata in una fase di PreBuild.

Il passaggio preliminare è simile a questo:

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

Il codice è qui:

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 grazie mille, perfetto. Un po 'lento, poiché ho tre file edmx che devo modificare, quindi potrei aggiungere una configurazione della soluzione solo per ripristinare dopo una distribuzione e rimuoverla dalla normale build. Pubblicherò una risposta ora con le informazioni per l'utilizzo di questo pratico strumento in un BeforeBuild (o AfterBuild) invece di pre-build. Molto apprezzato.
MemeDeveloper

3

Utilizzando la pratica app console di @ Vance sopra, ho usato quanto segue come evento 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>

Questo è super pratico, in quanto evita fastidiose ridistribuzioni. Grazie per aver condiviso Vance.

Ho aggiunto TF.exe alla cartella della soluzione Libreria e questo aiuta, poiché ora posso controllare i file edmx prima di provare a modificarli, come parte della build. Inoltre ho aggiunto questo con le condizioni, in modo che sia impostato su 2005 per le distribuzioni sul server e di nuovo su 2008 per le configurazioni sln della macchina Dev. Inoltre, per menzionare, è necessario aggiungere i file SetEdmxSqlVersion.exe (e .pdb) nella cartella Library (o in qualsiasi altro posto si desideri conservare questi bit).

Grazie mille @Vance. Davvero pulito, enorme risparmio di tempo e mantiene le mie build totalmente automatizzate e senza dolore :)


2

Si è verificato un problema simile con il 2012 rispetto al 2008. Può essere risolto con un evento BeforeBuild utilizzando XmlPeek e 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>

Se non ti piace la sostituzione automatica, puoi semplicemente sostituire l'attività XmlPoke con un'attività di errore.


Questo è molto meglio che usare un eseguibile esterno, consente a MSBuild di gestire internamente tutta la fantasia. Tutto ciò può essere facilmente concatenato tramite CallTargetattività di destinazione di pre-compilazione condizionali a seconda delle configurazioni di pubblicazione / compilazione. (Ad esempio, cambia solo durante la distribuzione in un ambiente sql2005)
ammesso

1

A beneficio delle persone che riscontrano lo stesso problema ma utilizzano Code First , dai un'occhiata alla mia risposta qui su come modificare ProviderManifestTokenCode First. Implica la creazione DbModelBuildermanuale e il passaggio di DbProviderInfoun'istanza (con il token appropriato) quando si chiama il Buildmetodo del generatore di modelli .


Penso che Type System Version=SQL Server 2005anche la stringa di connessione impostata possa funzionare
code4j

0

La soluzione migliore per me è invece di modificare manualmente il file EDMX è solo aprire edmx in modalità di progettazione e nel menu contestuale "Aggiorna modello dal database ...". Devi puntare alla giusta versione SQL, ovviamente, qualunque cosa sia per te.


1
Penso che questo sia un problema di OP: si è sviluppato contro un SQL locale 2008 ma poi è stato distribuito a SQL 2005.
StuartLC

Funziona a meno che tu non abbia accesso a un'istanza di SQL 2005.
Darcy

1
Un enorme svantaggio è che si tratta di un passaggio manuale e quindi verrà dimenticato.
Jowen

0

Abbiamo riscontrato questo errore su SQL2005 v.3, dove non lo avevamo su SQL2005 v.4.

L'aggiunta di SQL2005 alla stringa di connessione ha risolto il nostro problema specifico.

Non abbiamo ancora identificato il motivo e non volevamo modificare il codice per fornire il token come risolto in precedenza (problema manifestato durante la distribuzione).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.