[sql-server-2005] SQL Server 2008 및 SQL Server 2005 및 날짜 시간 사용

2008 데이터베이스에 대해 엔티티 프레임 워크 모델을 구축했습니다. 모두 2008 데이터베이스에 대해 정상적으로 작동합니다. 2005 데이터베이스에서 엔티티를 업데이트하려고하면이 오류가 발생합니다.

사용중인 SQL Server 버전은 'datetime2'데이터 형식을 지원하지 않습니다.

특히 데이터베이스를 구축 할 때 2008 기능을 사용하지 않았습니다. 코드에서 datetime2에 대한 참조를 찾을 수 없습니다. 그리고 예, 열은 데이터베이스에서 “datetime”으로 정의됩니다.



답변

빠른 Google이 해결책 처럼 보이는 것을 알려줍니다 .

파일 편집기에서 EDMX를 엽니 다 (또는 Visual Studio에서 “연결 프로그램…”을 선택하고 XML 편집기를 선택). 맨 위에는 스토리지 모델이 있으며 ProviderManifestToken 속성이 있습니다. 이 값은 2008이어야합니다. 2005로 변경하고 다시 컴파일하면 모든 것이 작동합니다.

참고 : 데이터베이스에서 모델을 업데이트 할 때마다이 작업을 수행해야합니다.


답변

라인의 빠른보기 :

<Schema Namespace="Foobar.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="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>

성가신 재배포를 방지하므로 매우 편리합니다. Vance를 공유해 주셔서 감사합니다.

TF.exe를 Library 솔루션 폴더에 추가했는데 이제 빌드의 일부로 edmx 파일을 편집하기 전에 확인할 수 있으므로 도움이됩니다. 또한 이것을 조건과 함께 추가하여 서버에 배포하려면 2005로 설정하고 Dev 컴퓨터 sln 구성에 대해서는 2008로 다시 설정했습니다. 또한 실제 SetEdmxSqlVersion.exe (및 .pdb) 파일을 Library 폴더 (또는 이러한 비트를 유지하려는 다른 위치)에 추가해야합니다.

@Vance 대단히 감사합니다. 정말 깔끔하고 엄청난 시간을 절약하고 빌드를 완전히 자동화하고 고통없이 유지합니다. 🙂


답변

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 작업을 오류 작업으로 간단히 교체 할 수 있습니다.


답변

동일한 문제가 발생하지만 Code First를 사용하는 사람들의 이익을 위해 Code First 를 변경하는 방법에 대한 여기 내 답변을 확인 하십시오ProviderManifestToken . 여기에는 모델 작성기의 메서드를 호출 할 때 DbModelBuilder수동으로 생성 DbProviderInfo하고 적절한 토큰을 사용하여 인스턴스를 전달하는 작업이 포함됩니다 Build.


답변

나에게 더 나은 해결책은 EDMX 파일을 수동으로 편집하는 대신 디자인 모드와 컨텍스트 메뉴 “데이터베이스에서 모델 업데이트 …”에서 edmx를 여는 것입니다. 물론 이것이 당신을 위해 무엇이든 올바른 SQL 버전을 가리켜 야합니다.