使用SQL Server 2008和SQL Server 2005以及date时间

我已经针对2008数据库构build了一个entity framework模型。 所有的作品对2008年的数据库。 当我尝试更新2005数据库上的实体时,出现此错误。

 正在使用的SQL Server版本不支持数据types“datetime2” 

当我build立数据库时,我特别没有使用任何2008function。 我无法在代码中find任何对datetime2的引用。 而且,该列在数据库中被定义为“datetime”。

一个快速的谷歌指向我看起来像解决scheme 。

在文件编辑器中打开您的EDMX(或在Visual Studio中打开…并selectXML Editor)。 在顶部你会发现存储模型,它有一个属性ProviderManifestToken。 这应该有价值2008.更改到2005年,重新编译,一切正常。

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

快速查看线路:

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

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

预build步骤如下所示:

 $(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的方便的控制台应用程序,我使用以下作为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添加到库解决scheme文件夹,这有助于,因为我现在可以检查edmx文件,然后尝试编辑它们,作为构build的一部分。 此外,我已经添加了这个条件,所以它设置为2005年部署到服务器,并回到2008年开发机器SLNconfiguration。 另外要提到的是,您需要将实际的SetEdmxSqlVersion.exe(和.pdb)文件添加到库文件夹(或任何您想要保留这些位的地方)。

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

对于遇到同样问题但使用Code First的人来说,请查看我的答案,以了解如何在Code First中更改ProviderManifestToken 。 它涉及手动创buildDbModelBuilder ,并在调用模型构build器的Build方法时传递DbProviderInfo实例(使用相应的标记)。

对我来说更好的解决scheme是,而不是手动编辑EDMX文件只是在devise模式下,并在上下文菜单“从数据库更新模型…”打开edmx。 你必须指向正确的SQL版本,当然这是你的。

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> 

如果您不喜欢自动replace,则可以简单地用错误任务replaceXmlPoke任务。