回答:
ファイルエディターでEDMXを開きます(またはVisual Studioで[...で開く]をクリックし、[XMLエディター]を選択します)。上部にはストレージモデルがあり、ProviderManifestToken属性があります。この値は2008である必要があります。これを2005に変更して、再コンパイルすると、すべてが機能します。
注:データベースからモデルを更新するたびに、これを行う必要があります。
これは非常にイライラするものであり、特定のSQLバージョンをターゲットにできるようにMSがそれを行わないことに決めたことに驚いています。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年に設定され、Devマシンのsln構成では2008年に設定されます。また、実際の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タスクをエラータスクに置き換えるだけです。
CallTarget
、パブリッシュ/ビルド構成に応じて、条件付きのプリビルドターゲットタスクを介して簡単にチェーンできます。(EGはsql2005環境に展開するときにのみ変更されます)
EDMXファイルを手動で編集する代わりに、デザインモードとコンテキストメニューの[データベースからモデルを更新...]でedmxを開くだけで、より良い解決策が得られます。もちろん、正しいSQLバージョンを指している必要があります。