使用 SQL Server 2008 和 SQL Server 2005 和日期时间
Posted
技术标签:
【中文标题】使用 SQL Server 2008 和 SQL Server 2005 和日期时间【英文标题】:Using SQL Server 2008 and SQL Server 2005 and date time 【发布时间】:2008-11-25 05:15:35 【问题描述】:我已经针对 2008 年的数据库构建了一个实体框架模型。对于 2008 数据库,一切正常。当我尝试更新 2005 数据库上的实体时,我收到此错误。
使用的 SQL Server 版本不支持数据类型 'datetime2
我在构建数据库时特别没有使用任何 2008 功能。我在代码中找不到对 datetime2 的任何引用。而且,是的,该列在数据库中被定义为“日期时间”。
【问题讨论】:
【参考方案1】:一个快速的谷歌将我指向看起来像solution。
在文件编辑器中打开您的 EDMX(或在 Visual Studio 中“打开方式...”并选择 XML 编辑器)。在顶部,您会找到存储模型,它有一个属性 ProviderManifestToken。这应该具有值 2008。将其更改为 2005,重新编译,一切正常。
注意:每次从数据库更新模型时都必须这样做。
【讨论】:
我错误地投了反对票,取消了那个,但现在不能做我真正想做的事,那就是投票!感谢您发现问题。如果我理解正确,由于从数据库更新模型,值是否从 2005 年更改为 2008 年,其中数据库是 SQL 2008 DB?在我的环境中,我的开发机器有 SQL 2008,但测试环境有 2005(生产环境也有)。在我们迁移到 2008 年之前,我是否认为这种情况会继续发生? 我一般设置为2005,也就是生产数据库;我正在使用 2008 进行开发。 2008 是向后兼容的,所以没有问题。这也将在更新/生成后更改回来。在经历了痛苦的经历后,我总是在签入 EDMX 时验证这一点。 这个修复对我不起作用?? forums.asp.net/p/1770522/4838628.aspx/… 如果在 LightSwitch 中发生这种情况,请参阅我的博客文章,其中解释了如何在 lsml 文件中修复它(因为无法直接访问 LS 中的 edmx 文件):lightswitchcentral.net.au/Blog/tabid/83/EntryId/27/… 这是唯一的解决方案,但您应该知道,每次修改 edmx 时都需要这样做,因为它会自行恢复【参考方案2】:快速查看线路:
<Schema Namespace="Foobar.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005" >
【讨论】:
【参考方案3】:这非常令人沮丧,我很惊讶 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);
【讨论】:
@Vance 非常感谢,完美。有点慢,因为我需要更改三个 edmx 文件,因此可能会添加一个解决方案配置,只是为了在部署后恢复,并将其从通常的构建中删除。现在将发布一个答案,其中包含在 BeforeBuild(或 AfterBuild)而不是预构建中使用这个方便的工具的信息。非常感谢。【参考方案4】:使用上面@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 用于开发机器 sln 配置。还要提一下,您需要将实际的 SetEdmxSqlVersion.exe(和 .pdb)文件添加到 Library 文件夹(或您想要保留这些位的任何其他位置)。
非常感谢@Vance。真的很整洁,节省了大量时间,让我的构建完全自动化且无痛:)
【讨论】:
【参考方案5】:在 2012 年与 2008 年有类似的问题。它可以通过使用 XmlPeek 和 XmlPoke 的 BeforeBuild 事件来解决:
<Target Name="BeforeBuild">
<XmlPeek XmlInputPath="$(ProjectDir)MyModel.edmx"
Namespaces="<Namespace Prefix='edmx' Uri='http://schemas.microsoft.com/ado/2009/11/edmx'/><Namespace Prefix='ssdl' Uri='http://schemas.microsoft.com/ado/2009/11/edm/ssdl'/>"
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="<Namespace Prefix='edmx' Uri='http://schemas.microsoft.com/ado/2009/11/edmx'/><Namespace Prefix='ssdl' Uri='http://schemas.microsoft.com/ado/2009/11/edm/ssdl'/>"
Query="/edmx:Edmx/edmx:Runtime/edmx:StorageModels/ssdl:Schema/@ProviderManifestToken"
Value="2008">
</XmlPoke>
</Target>
如果您不喜欢自动替换,您可以简单地将 XmlPoke 任务替换为错误任务。
【讨论】:
这比使用外部可执行文件要好得多,允许 MSBuild 在内部处理所有花哨的东西。这一切都可以通过CallTarget
有条件的预构建目标任务轻松链接,具体取决于发布/构建配置。 (EG只在部署到sql2005环境时改变)【参考方案6】:
为了方便遇到相同问题但使用 Code First 的人,请查看my answer here,了解如何在 Code First 中更改 ProviderManifestToken
。它涉及在调用模型构建器的Build
方法时手动创建DbModelBuilder
并传递DbProviderInfo
实例(带有适当的令牌)。
【讨论】:
我认为在连接字符串中设置Type System Version=SQL Server 2005
也可以工作【参考方案7】:
对我来说更好的解决方案不是手动编辑 EDMX 文件,而是在设计模式和上下文菜单“从数据库更新模型...”中打开 edmx。 当然,无论这对你来说是什么,你都必须指向正确的 SQL 版本。
【讨论】:
我认为这是 OP 的问题 - 他针对本地 SQL 2008 开发,然后部署到 SQL 2005。 此方法有效,除非您无权访问 SQL 2005 实例。 一个巨大的缺点是这是一个手动步骤,因此会被遗忘。【参考方案8】:我们在 SQL2005 v.3 上遇到了这个错误,而在 SQL2005 v.4 上没有。
将 SQL2005 添加到连接字符串解决了我们的特定问题。
我们尚未确定原因,也不想修改代码以提供上述解决的令牌(部署期间出现的问题)。
【讨论】:
以上是关于使用 SQL Server 2008 和 SQL Server 2005 和日期时间的主要内容,如果未能解决你的问题,请参考以下文章
安装SQL SERVER 2008,出现“查找sql server 2008安装媒体”的问题
如何用SQL SERVER 2005连接SQL SERVER 2008