Answers:
一个快速的谷歌指出我看起来像解决方案。
在文件编辑器中打开EDMX(或在Visual Studio中“用...打开”,然后选择XML编辑器)。在顶部,您将找到存储模型,它具有ProviderManifestToken属性。该值应为2008。将其更改为2005,重新编译,一切正常。
注意:每次从数据库更新模型时,都必须这样做。
这非常令人沮丧,我很惊讶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方便的控制台应用程序,我将以下内容用作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。真正整洁,节省大量时间,并使我的构建完全自动化且无痛苦:)
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任务替换为Error任务即可。
CallTarget
条件性的预构建目标任务轻松链接,具体取决于发布/构建配置。(仅当部署到sql2005环境时,EG才会更改)
对我来说,更好的解决方案是在设计模式下和上下文菜单“从数据库更新模型...”中打开edmx,而不是手动编辑EDMX文件。当然,无论您要使用哪种版本,都必须指向正确的SQL版本。