web-dev-qa-db-ja.com

SQL Server 2008およびSQL Server 2005と日時の使用

2008年のデータベースに対してエンティティフレームワークモデルを構築しました。 2008年のデータベースに対してはすべて正常に動作します。 2005データベースのエンティティを更新しようとすると、このエラーが発生します。

使用中のSQL Serverのバージョンは、データ型「datetime2」をサポートしていません

データベースを構築したとき、2008年の機能は特に使用しませんでした。コードにdatetime2への参照が見つかりません。そして、はい、列はデータベースで「datetime」として定義されています。

118
Monroecheeseman

簡単なグーグルで solution のように見えるものが表示されます。

EDMXをファイルエディターで開きます(またはVisual Studioで「…で開く」を選択して、XMLエディターを選択します)。上部にストレージモデルがあり、属性ProviderManifestTokenがあります。これには2008年の値が必要です。2005年に変更し、再コンパイルするとすべてが機能します。

注:データベースからモデルを更新するたびにこれを行う必要があります。

190

ラインのクイックビュー:

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

これは非常にイライラするものであり、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);
            }
        }
    }
}
11
Vance Kessler

上記の@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>

これは面倒な再デプロイメントを避けるため、非常に便利です。Vanceを共有していただきありがとうございます。

ライブラリソリューションフォルダーにTF.exeを追加しました。これは、ビルドの一部としてedmxファイルを編集する前にチェックアウトできるようになったためです。また、これを条件付きで追加したため、サーバーへの展開では2005に設定され、Devマシンsln構成では2008に戻ります。また、実際のSetEdmxSqlVersion.exe(および.pdb)ファイルをライブラリフォルダー(またはこれらのビットを保持する他の場所)に追加する必要があります。

@Vanceに感謝します。本当にすっきりとした時間の節約になり、ビルドが完全に自動化され、痛みがなくなります:)

4
MemeDeveloper

同じ問題に遭遇したがCode Firstを使用している人々のために、 my answer here 変更方法について確認してくださいCode FirstのProviderManifestToken。モデルビルダーのDbModelBuilderメソッドを呼び出すときに、DbProviderInfoを手動で作成し、Buildインスタンスを(適切なトークンとともに)渡す必要があります。

2
sinelaw

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タスクをエラータスクに置き換えるだけです。

2
Edgar

私にとってより良い解決策は、手動でEDMXファイルを編集する代わりに、設計モードでコンテキストメニュー「データベースからモデルを更新...」でedmxを開くことです。もちろん、適切なSQLバージョンを指定する必要があります。

1
Marek

SQL2005 v.3ではこのエラーが発生しましたが、SQL2005 v.4では発生しませんでした。

接続文字列にSQL2005を追加すると、特定の問題が修正されました。

理由はまだ特定されておらず、上記で解決されたトークンを提供するためにコードを変更したくありませんでした(展開中に明らかになった問題)。

0
Brian H