117

He creado un modelo de estructura de entidad con una base de datos de 2008. Todo funciona bien contra la base de datos 2008. Cuando trato de actualizar la entidad en una base de datos de 2005 obtengo este error.Uso de SQL Server 2008 y SQL Server 2005 y fecha y hora

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

Específicamente no utilicé las características 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.

Respuesta

192

Un Google rápido me señala lo que parece ser el solution.

Abra su EDMX en un editor de archivos (o "abra con ..." en Visual Studio y seleccione el 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, recompile y todo funcione.

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

+2

He votado esto por error, deshice eso, pero ahora no puedo hacer lo que realmente quería hacer, ¡que es votar por él! Gracias por encontrar el problema. Si entiendo correctamente, ¿el valor cambia de 2005 a 2008 debido a la actualización del modelo de la base de datos, donde la base de datos es un SQL 2008 DB? En mi entorno, mi máquina desarrolladora tiene SQL 2008, pero el entorno de prueba tiene 2005 (que también tiene producción). Hasta que migremos a 2008, ¿estoy en lo cierto al suponer que esto seguirá ocurriendo? – jamiebarrow

+0

Generalmente establezco esto en 2005, que es la base de datos de producción; Estoy usando 2008 para el desarrollo. 2008 es compatible con versiones anteriores, por lo que no hay problemas. También esto se cambiará después de una actualización/generar. Siempre valido esto al registrar el EDMX después de una experiencia amarga. –

+0

WOW, excelente repetición, gracias Rechard –

12

vista rápida de la línea:

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

mejor solución para mí es en lugar de editar manualmente el archivo EDMX es sólo edmx abierto en el modo de diseño y en el menú contextual "Modelo de actualización de base de datos ...". Tienes que estar apuntando a la versión SQL correcta, por supuesto, sea lo que sea para ti.

+1

Creo que esto es OP problema: desarrolló un SQL 2008 local pero luego se implementó en SQL 2005. – StuartLC

+0

Esto funciona a menos que no tenga acceso a una instancia de SQL 2005. – Darcy

+1

Una gran desventaja es que es un paso manual y, por lo tanto, será olvidado. – Jowen

11

Esto es muy frustrante y me sorprende que MS haya decidido no hacerlo para poder orientar una versión de SQL determinada. Para asegurarnos de que estamos orientados al 2005, escribí una aplicación de consola simple y la llamo en un paso PreBuild.

El paso prebuild 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); 
      } 
     } 
    } 
} 
+0

Gracias, una solución simple al problema molesto – Brian

+0

@Vance muchas gracias, perfecto. Un poco lento, ya que tengo tres archivos edmx que necesito cambiar, por lo que podría agregar una configuración de solución solo para revertir después de una implementación y eliminarla de la compilación habitual. Publicaremos una respuesta ahora con la información para usar esta práctica herramienta en BeforeBuild (o AfterBuild) en lugar de precompilar. Muy apreciado. – MemeDeveloper

4

Usando @ aplicación de consola práctica de Vance anterior, he utilizado la 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 super práctico, ya que evita el redespliegue molesto. Gracias por compartir Vance.

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

Muchas gracias @Vance. realmente aseado, ahorro de tiempo enorme y mantiene mi construye totalmente automatizado y sin dolor :)

2

Para el beneficio de las personas que se encuentran con el mismo problema, pero están utilizando Código En primer lugar, echa un vistazo a my answer here acerca de cómo cambiar la ProviderManifestToken en Primero el código Se trata de crear un DbModelBuilder manualmente y pasar una instancia DbProviderInfo (con el token apropiado) al llamar al método Build del generador de modelos.

+0

Creo que el conjunto 'Type System Version = SQL Server 2005' en la cadena de conexión también puede funcionar – code4j

1

tenido un problema similar con el año 2012 respecto a 2008. Se puede solucionar 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 automatizado, puede simplemente reemplazar la tarea XmlPoke con un error tarea.

+0

Esto es mucho mejor que usar un archivo ejecutable externo, permite que MSBuild maneje todo el capricho internamente. Todo esto se puede encadenar fácilmente a través de las tareas de destino pre-compilación 'CallTarget' dependiendo de las configuraciones de publicación/compilación. (Por ejemplo, solo cambia cuando se implementa en un entorno sql2005) – admalledd

0

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

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

No hemos identificado por qué todavía y no hemos querido modificar el código para proporcionar el token como se ha solucionado anteriormente (problema manifestado durante la implementación).

Cuestiones relacionadas