首页 文章

使用SQL Server 2008和SQL Server 2005以及日期时间

提问于
浏览
118

我已经针对2008数据库构建了一个实体框架模型 . 一切都适用于2008数据库 . 当我尝试更新2005数据库上的实体时,我收到此错误 .

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

我在构建数据库时没有使用任何2008功能 . 我在代码中找不到对datetime2的任何引用 . 并且,是的,该列在数据库中被定义为“datetime” .

8 回答

  • 2

    一个快速的谷歌指向我看起来像solution .

    在文件编辑器中打开EDMX(或在Visual Studio中“以...打开”并选择XML编辑器) . 在顶部,您将找到存储模型,它具有属性ProviderManifestToken . 这应该具有值2008.将其更改为2005,重新编译,一切正常 .

    注意:每次从数据库更新模型时都必须执行此操作 .

  • 11

    快速查看线:

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

    这是非常令人沮丧的,我很惊讶MS决定不这样做,所以你可以针对给定的SQL版本 . 为了确保我们的目标是2005年,我编写了一个简单的控制台应用程序并在PreBuild步骤中调用它 .

    预建步骤如下所示:

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

    代码在这里:

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

    使用上面的@Vance方便的控制台应用程序,我使用以下内容作为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>
    

    This is super handy, as avoids annoying redeployment. Thanks for sharing Vance.

    我已将TF.exe添加到Library解决方案文件夹中,这有助于,因为我现在可以在尝试编辑之前检查edmx文件,作为构建的一部分 . 此外,我添加了条件,因此它设置为2005以便部署到服务器并返回到2008年的Dev机器sln配置 . 另外要提到的是,您需要将实际的SetEdmxSqlVersion.exe(和.pdb)文件添加到Library文件夹(或者您希望保留这些位的任何其他位置) .

    非常感谢@Vance . 非常整洁,节省大量时间,让我的构建完全自动化,无痛苦:)

  • 1

    为了使遇到相同问题但使用 Code First 的人员的利益,请查看my answer here,了解如何更改Code First中的 ProviderManifestToken . 它涉及手动创建 DbModelBuilder 并在调用模型构建器的 Build 方法时传递 DbProviderInfo 实例(带有相应的标记) .

  • 2

    与2012年和2008年有类似的问题 . 可以使用XmlPeek和XmlPoke通过BeforeBuild事件解决:

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

    如果您不喜欢自动替换,则可以使用Error任务替换XmlPoke任务 .

  • 4

    对我来说更好的解决方案是手动编辑EDMX文件只是在设计模式和上下文菜单“从数据库更新模型......”中打开edmx . 无论如何,你必须指向正确的SQL版本 .

  • 0

    我们在SQL2005 v.3上遇到了这个错误,我们在SQL2005 v.4上没有它 .

    将SQL2005添加到连接字符串修复了我们的具体问题 .

    我们还没有确定原因,并且不想修改代码以提供上面解决的令牌(在部署期间出现的问题) .

相关问题