ใช้ SQL Server 2008 และ SQL Server 2005 และวันเวลา


118

ฉันได้สร้างแบบจำลองกรอบเอนทิตีเทียบกับฐานข้อมูลปี 2008 ทั้งหมดใช้ได้กับฐานข้อมูลปี 2008 เมื่อฉันพยายามอัปเดตเอนทิตีบนฐานข้อมูลปี 2005 ฉันได้รับข้อผิดพลาดนี้

เวอร์ชันของ SQL Server ที่ใช้งานไม่รองรับประเภทข้อมูล 'datetime2

ฉันไม่ได้ใช้คุณลักษณะใด ๆ ในปี 2008 โดยเฉพาะเมื่อฉันสร้างฐานข้อมูล ฉันไม่พบการอ้างอิงถึง datetime2 ในโค้ด และใช่คอลัมน์นี้ถูกกำหนดให้เป็น "วันที่และเวลา" ในฐานข้อมูล

คำตอบ:


189

Google ฉบับย่อชี้ให้ฉันเห็นว่าโซลูชันนี้มีลักษณะอย่างไร

เปิด EDMX ของคุณในโปรแกรมแก้ไขไฟล์ (หรือ“ เปิดด้วย…” ใน Visual Studio แล้วเลือกตัวแก้ไข XML) ที่ด้านบนคุณจะพบโมเดลพื้นที่เก็บข้อมูลและมีแอตทริบิวต์ ProviderManifestToken สิ่งนี้ควรมีค่า 2008 เปลี่ยนเป็นปี 2005 คอมไพล์ใหม่และทุกอย่างใช้งานได้

หมายเหตุ: คุณจะต้องทำสิ่งนี้ทุกครั้งที่อัปเดตโมเดลจากฐานข้อมูล


2
ฉันลงคะแนนสิ่งนี้โดยไม่ได้ตั้งใจยกเลิกสิ่งนั้น แต่ตอนนี้ไม่สามารถทำในสิ่งที่ฉันอยากทำจริงๆซึ่งก็คือโหวตมัน! ขอบคุณสำหรับการค้นหาปัญหา ถ้าฉันเข้าใจถูกต้องค่าจะเปลี่ยนจากปี 2005 ถึง 2008 เนื่องจากการอัปเดตโมเดลจากฐานข้อมูลโดยที่ฐานข้อมูลเป็น SQL 2008 DB หรือไม่ ในสภาพแวดล้อมของฉันเครื่องนักพัฒนาของฉันมี SQL 2008 แต่สภาพแวดล้อมการทดสอบมีปี 2005 (ซึ่งมีการผลิตด้วย) จนกว่าเราจะย้ายไปปี 2008 ฉันคิดถูกหรือเปล่าว่าสิ่งนี้จะเกิดขึ้นเรื่อย ๆ
jamiebarrow

โดยทั่วไปฉันตั้งค่านี้เป็นปี 2548 ซึ่งเป็นฐานข้อมูลการผลิต ฉันใช้ปี 2008 เพื่อการพัฒนา 2008 เข้ากันได้กับรุ่นเก่าจึงไม่มีปัญหา นอกจากนี้สิ่งนี้จะเปลี่ยนกลับหลังจากอัปเดต / สร้าง ฉันมักจะตรวจสอบสิ่งนี้เมื่อตรวจสอบใน EDMX หลังจากประสบการณ์ที่ขมขื่น
Richard Harrison

การแก้ไขนี้ไม่ได้ผลสำหรับฉัน ?? forums.asp.net/p/1770522/4838628.aspx/…
Welsh King

หากสิ่งนี้เกิดขึ้นใน LightSwitch โปรดดูบล็อกโพสต์ของฉันที่อธิบายวิธีแก้ไขในไฟล์ lsml (เนื่องจากไม่มีการเข้าถึงโดยตรงไปยังไฟล์ edmx ใน LS): lightswitchcentral.net.au/Blog/tabid/83/EntryId/27/ …
ญาณดูรัน

เป็นทางออกเดียว แต่คุณควรทราบว่าคุณต้องทำสิ่งนี้ทุกครั้งที่คุณแก้ไข edmx เนื่องจากจะเปลี่ยนกลับเอง
Dave Hogan


10

สิ่งนี้น่าผิดหวังมากและฉันประหลาดใจที่ MS ตัดสินใจที่จะไม่ทำเพื่อให้คุณสามารถกำหนดเป้าหมายเวอร์ชัน SQL ที่กำหนดได้ เพื่อให้แน่ใจว่าเรากำหนดเป้าหมายในปี 2548 ฉันได้เขียนแอปคอนโซลง่ายๆและเรียกมันว่าในขั้นตอนก่อนสร้าง

ขั้นตอนการสร้างล่วงหน้ามีลักษณะดังนี้:

$(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);
            }
        }
    }
}

@ แวนซ์ขอบคุณมากสมบูรณ์แบบ ช้าเล็กน้อยเนื่องจากฉันมีไฟล์ edmx สามไฟล์ที่ฉันต้องการเปลี่ยนแปลงดังนั้นอาจเพิ่มการกำหนดค่าโซลูชันเพื่อเปลี่ยนกลับหลังจากการปรับใช้และลบออกจากบิลด์ปกติ จะโพสต์คำตอบพร้อมข้อมูลสำหรับการใช้เครื่องมือที่มีประโยชน์นี้ใน BeforeBuild (หรือ AfterBuild) แทนการสร้างล่วงหน้า ชื่นชมมาก
MemeDeveloper

3

การใช้แอปคอนโซลที่มีประโยชน์ของ @ 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 สำหรับการปรับใช้กับเซิร์ฟเวอร์และกลับไปที่ 2008 สำหรับการกำหนดค่า sln ของเครื่อง Dev นอกจากนี้คุณต้องเพิ่มไฟล์ SetEdmxSqlVersion.exe (และ. pdb) ที่แท้จริงลงในโฟลเดอร์ Library (หรือที่ใดก็ตามที่คุณต้องการเก็บบิตเหล่านี้ไว้)

ขอบคุณมาก @Vance. เรียบร้อยประหยัดเวลามากและช่วยให้งานสร้างของฉันเป็นไปโดยอัตโนมัติและปราศจากความเจ็บปวด :)


2

มีปัญหาคล้ายกันกับ 2012 กับ 2008 สามารถแก้ไขได้ด้วยเหตุการณ์ BeforeBuild โดยใช้ XmlPeek และ XmlPoke:

   <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 ด้วยงาน Error


สิ่งนี้ดีกว่าการใช้ปฏิบัติการภายนอกมากช่วยให้ MSBuild จัดการกับสิ่งที่น่าสนใจทั้งหมดภายในได้ ทั้งหมดนี้สามารถถูกผูกมัดได้อย่างง่ายดายผ่านCallTargetภารกิจเป้าหมายที่สร้างไว้ล่วงหน้าตามเงื่อนไขขึ้นอยู่กับการกำหนดค่าการเผยแพร่ / สร้าง (EG เปลี่ยนแปลงเฉพาะเมื่อปรับใช้กับสภาพแวดล้อม sql2005)
ยอมรับ

1

เพื่อประโยชน์ของผู้ที่พบปัญหาเดียวกัน แต่กำลังใช้Code Firstโปรดดูคำตอบของฉันที่นี่เกี่ยวกับวิธีเปลี่ยนProviderManifestTokenใน Code First มันเกี่ยวข้องกับการสร้างDbModelBuilderด้วยตนเองและส่งผ่านDbProviderInfoอินสแตนซ์ (ด้วยโทเค็นที่เหมาะสม) เมื่อเรียกใช้Buildเมธอดของตัวสร้างโมเดล


ฉันคิดว่าการตั้งค่าType System Version=SQL Server 2005ในสตริงการเชื่อมต่ออาจใช้งานได้
code4j

0

ทางออกที่ดีกว่าสำหรับฉันคือแทนที่จะแก้ไขไฟล์ EDMX ด้วยตนเองเพียงเปิด edmx ในโหมดออกแบบและในเมนูบริบท "อัปเดตโมเดลจากฐานข้อมูล ... " คุณต้องชี้ไปที่เวอร์ชัน SQL ที่ถูกต้องแน่นอนว่าสิ่งนี้เหมาะสำหรับคุณ


1
ฉันคิดว่านี่เป็นปัญหาของ OP - เขาพัฒนาขึ้นโดยเทียบกับ SQL ภายในเครื่อง แต่นำไปใช้กับ SQL 2005 แล้ว
StuartLC

สิ่งนี้ใช้ได้เว้นแต่คุณจะไม่มีสิทธิ์เข้าถึงอินสแตนซ์ SQL 2005
Darcy

1
ข้อเสียอย่างมากคือมันเป็นขั้นตอนแบบแมนนวลจึงลืมไป
Jowen

0

เรามีข้อผิดพลาดนี้ใน SQL2005 v.3 โดยที่เราไม่มีบน SQL2005 v.4

การเพิ่ม SQL2005 ลงในสตริงการเชื่อมต่อช่วยแก้ปัญหาเฉพาะของเรา

เรายังไม่ได้ระบุสาเหตุและไม่ต้องการแก้ไขโค้ดเพื่อให้โทเค็นตามที่แก้ไขด้านบน (ปัญหาที่ปรากฏระหว่างการปรับใช้)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.