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


118

我已经针对2008数据库建立了一个实体框架模型。对于2008数据库,一切正常。当我尝试在2005数据库上更新实体时,出现此错误。

使用的SQL Server版本不支持数据类型'datetime2

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

Answers:


189

一个快速的谷歌指出我看起来像解决方案

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

注意:每次从数据库更新模型时,都必须这样做。


2
我错误地否决了这一建议,但并没有做到,但是现在我不能真正做到的就是投票!感谢您找到问题。如果我理解正确,那么从数据库(其中数据库是SQL 2008 DB)更新模型后,该值在2005年到2008年之间是否会发生变化?在我的环境中,我的开发人员计算机具有SQL 2008,但是测试环境具有2005(生产也具有SQL Server)。在迁移到2008年之前,我是否可以假设这种情况会继续发生?
jamiebarrow

我通常将其设置为2005,这是生产数据库。我正在使用2008进行开发。2008向后兼容,所以没有问题。也可以在更新/生成后将其更改回。经历过痛苦之后,我总是在签入EDMX时对此进行验证。
理查德·哈里森

此修复程序对我不起作用?forums.asp.net/p/1770522/4838628.aspx/…–
威尔士国王,

如果发生这种情况在LightSwitch中,见我的博客文章,解释如何解决它在LSML文件(有在LS的EDMX文件不能直接访问):lightswitchcentral.net.au/Blog/tabid/83/EntryId/27/ …
Yann Duran 2013年

这是唯一的解决方案,但您应该意识到,每次修改edmx时都需要这样做,因为它会自动还原
Dave Hogan

11

快速浏览线:

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

10

这非常令人沮丧,我很惊讶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);
            }
        }
    }
}

@万斯非常感谢,完美。有点慢,因为我需要更改三个edmx文件,因此可能添加解决方案配置只是为了在部署后还原,并将其从常规构建中删除。现在将发布有关在Prebuild(或AfterBuild)而不是预构建中使用此便捷工具的信息的答案。非常感谢。
MemeDeveloper 2012年

3

使用上面的@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>

这非常方便,因为避免了烦人的重新部署。感谢您分享万斯。

我已将TF.exe添加到“库”解决方案文件夹中,这对您有所帮助,因为作为构建的一部分,我现在可以在尝试编辑edmx文件之前将其检出。另外,我还添加了一些条件,以便将其设置为2005(用于服务器部署),将其设置为2008(用于Dev machine sln配置)。另外要提到的是,您需要将实际的SetEdmxSqlVersion.exe(和.pdb)文件添加到Library文件夹(或您想保留这些位的其他位置)。

非常感谢@Vance。真正整洁,节省大量时间,并使我的构建完全自动化且无痛苦:)


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>

如果您不喜欢自动替换,则只需将XmlPoke任务替换为Error任务即可。


这比使用外部可执行文件要好得多,它允许MSBuild在内部处理所有花哨的内容。所有这些都可以通过CallTarget条件性的预构建目标任务轻松链接,具体取决于发布/构建配置。(仅当部署到sql2005环境时,EG才会更改)
冲突

1

为了使遇到相同问题但正在使用Code First的人们受益,请在此处查看我的答案,以了解如何更改ProviderManifestTokenCode First。它涉及DbModelBuilder手动创建DbProviderInfo模型,并在调用模型构建器的Build方法时传递实例(使用适当的令牌)。


我认为Type System Version=SQL Server 2005在连接字符串中设置也可能会起作用
code4j

0

对我来说,更好的解决方案是在设计模式下和上下文菜单“从数据库更新模型...”中打开edmx,而不是手动编辑EDMX文件。当然,无论您要使用哪种版本,都必须指向正确的SQL版本。


1
我认为这是OP的问题-他开发了针对本地SQL 2008,但随后部署到2005年SQL
StuartLC

除非您无权访问SQL 2005实例,否则此方法有效。
达西,2012年

1
一个巨大的缺点是这是一个手动步骤,因此将被遗忘。
Jowen 2014年

0

我们在SQL2005 v.3上有此错误,而在SQL2005 v.4上则没有。

将SQL2005添加到连接字符串可解决我们的特定问题。

我们尚未确定原因,也不想修改代码以提供上述解决的令牌(部署期间出现的问题)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.