Pregunta

He creado un modelo de marco de entidad contra una base de datos de 2008. Todo funciona bien con la base de datos de 2008. Cuando intento actualizar la entidad en una base de datos de 2005, aparece este error.

The version of SQL Server in use does not support datatype 'datetime2

Específicamente no utilicé ninguna característica de 2008 cuando construí la base de datos. No puedo encontrar ninguna referencia a datetime2 en el código. Y sí, la columna se define como " datetime " en la base de datos

¿Fue útil?

Solución

Un rápido google me señala lo que parece el solución .

Abra su EDMX en un editor de archivos (o & # 8220; ábralo con & # 8230; & # 8221; en Visual Studio y seleccione Editor XML). En la parte superior, encontrará el modelo de almacenamiento y tiene un atributo ProviderManifestToken. Esto debe tener el valor 2008. Cambie eso a 2005, vuelva a compilar y todo funcionará.

NOTA: Deberá hacer esto cada vez que actualice el modelo desde la base de datos.

Otros consejos

Vista rápida de línea:

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

Esto es muy frustrante y me sorprende que MS haya decidido no hacerlo para que pueda apuntar a una versión SQL dada. Para asegurarnos de que estamos apuntando a 2005, escribí una aplicación de consola simple y la llamo en un paso PreBuild.

El paso previo a la construcción se ve así:

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

El código está aquí:

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);
            }
        }
    }
}

Utilizando la práctica aplicación de consola de @ Vance anterior, utilicé lo siguiente como un 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>

Esto es muy útil, ya que evita la molesta redistribución. Gracias por compartir Vance.

Agregué TF.exe a la carpeta de la solución Biblioteca y esto ayuda, ya que ahora puedo ver los archivos edmx antes de intentar editarlos, como parte de la compilación. También he agregado esto con condiciones, para que se establezca en 2005 para implementaciones en el servidor y de nuevo en 2008 para las configuraciones sln de la máquina Dev. También para mencionar que necesita agregar los archivos SetEdmxSqlVersion.exe (y .pdb) reales a la carpeta Biblioteca (o en cualquier otro lugar donde desee guardar estos bits).

Muchas gracias @Vance. Realmente ordenado, ahorrador de tiempo masivo y mantiene mis compilaciones totalmente automatizadas y sin dolor :)

Para el beneficio de las personas que enfrentan el mismo problema pero están usando Code First , consulte mi respuesta aquí sobre cómo cambiar el ProviderManifestToken en Code First. Implica crear un DbModelBuilder manualmente y pasar una instancia de DbProviderInfo (con el token apropiado) al llamar al método Build del creador de modelos.

Tuve un problema similar con 2012 vs. 2008. Se puede resolver con un evento BeforeBuild usando XmlPeek y 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 no le gusta el reemplazo automático, simplemente puede reemplazar la tarea XmlPoke con una tarea de Error.

Una mejor solución para mí es que, en lugar de editar manualmente el archivo EDMX, simplemente abra edmx en modo de diseño y en el menú contextual "Actualizar modelo de la base de datos ...". Tiene que estar apuntando a la versión correcta de SQL, por supuesto, sea lo que sea para usted.

Tuvimos este error en SQL2005 v.3, donde no lo teníamos en SQL2005 v.4.

Agregar SQL2005 a la cadena de conexión solucionó nuestro problema específico.

Todavía no hemos identificado por qué, y no queríamos modificar el código para proporcionar el token tal como se resolvió anteriormente (problema manifestado durante la implementación).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top