117

Tôi đã xây dựng mô hình khung thực thể dựa vào cơ sở dữ liệu năm 2008. Tất cả các công trình đều chống lại cơ sở dữ liệu 2008. Khi tôi cố gắng cập nhật thực thể trên cơ sở dữ liệu năm 2005, tôi nhận được lỗi này.Sử dụng SQL Server 2008 và SQL Server 2005 và ngày giờ

The version of SQL Server in use does not support datatype 'datetime2

Tôi đặc biệt không sử dụng bất kỳ tính năng nào của năm 2008 khi tôi xây dựng cơ sở dữ liệu. Tôi không thể tìm thấy bất kỳ tham chiếu đến datetime2 trong mã. Và, có cột được định nghĩa là "datetime" trong cơ sở dữ liệu.

Trả lời

192

Google nhanh chóng chỉ cho tôi những gì trông giống như solution.

Mở EDMX của bạn trong trình chỉnh sửa tệp (hoặc “mở bằng…” trong Visual Studio và chọn Trình chỉnh sửa XML). Ở phía trên, bạn sẽ tìm thấy mô hình lưu trữ và nó có một thuộc tính ProviderManifestToken. Điều này cần phải có giá trị 2008. Thay đổi đó đến năm 2005, biên dịch lại và tất cả mọi thứ hoạt động.

LƯU Ý: Bạn sẽ phải thực hiện việc này mỗi khi bạn cập nhật mô hình từ cơ sở dữ liệu.

+2

Tôi đã bỏ phiếu này do nhầm lẫn, nhưng không thể thực hiện được những gì tôi thực sự muốn làm mà bỏ phiếu cho nó! Cảm ơn bạn đã tìm sự cố. Nếu tôi hiểu chính xác, giá trị có thay đổi từ năm 2005 đến 2008 do cập nhật mô hình từ cơ sở dữ liệu, nơi cơ sở dữ liệu là một SQL 2008 DB không? Trong môi trường của tôi, máy phát triển của tôi có SQL 2008, nhưng môi trường thử nghiệm có 2005 (sản xuất nào cũng vậy). Cho đến khi chúng tôi di chuyển đến năm 2008, tôi có đúng là giả định rằng điều này sẽ tiếp tục xảy ra không? – jamiebarrow

+0

Tôi thường đặt điều này vào năm 2005, đó là cơ sở dữ liệu sản xuất; Tôi đang sử dụng năm 2008 để phát triển. 2008 là tương thích ngược nên không có vấn đề gì. Ngoài ra, điều này sẽ được thay đổi trở lại sau khi cập nhật/tạo. Tôi luôn luôn xác nhận điều này khi kiểm tra trong EDMX sau khi trải nghiệm cay đắng. –

+0

WOW, phát lại tuyệt vời, nhờ Rechard –

12

Quick view của dòng:

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

Better giải pháp đối với tôi là thay vì bằng tay chỉnh sửa tập tin EDMX chỉ là edmx mở trong chế độ thiết kế và trong menu ngữ cảnh "Cập nhật mô hình từ cơ sở dữ liệu ...". Bạn phải trỏ đến đúng phiên bản SQL của khóa học bất kể điều này là dành cho bạn.

+1

Tôi nghĩ đây là OP vấn đề - ông đã phát triển chống lại một SQL địa phương năm 2008 nhưng sau đó triển khai SQL 2005. – StuartLC

+0

Điều này hoạt động trừ khi bạn không có quyền truy cập vào một phiên bản SQL 2005. – Darcy

+1

Một bất lợi lớn là nó là một bước hướng dẫn sử dụng, và do đó sẽ bị lãng quên. – Jowen

11

Điều này rất bực bội và tôi ngạc nhiên khi MS quyết định không tạo nó để bạn có thể nhắm mục tiêu một phiên bản SQL đã cho. Để chắc chắn rằng chúng tôi đang nhắm mục tiêu năm 2005, tôi đã viết một ứng dụng giao diện điều khiển đơn giản và gọi nó trong bước PreBuild.

Bước prebuild trông như thế này:

$(SolutionDir)Artifacts\SetEdmxVer\SetEdmxSqlVersion $(ProjectDir)MyModel.edmx 2005 

Mã này là ở đây:

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); 
      } 
     } 
    } 
} 
+0

Cảm ơn, một giải pháp đơn giản cho vấn đề khó chịu – Brian

+0

@Vance cảm ơn rất nhiều, hoàn hảo. Một chút chậm, như tôi có ba tập tin edmx tôi cần phải thay đổi, vì vậy có thể thêm một cấu hình giải pháp chỉ để trở lại sau khi triển khai, và loại bỏ nó từ xây dựng thông thường. Sẽ đăng câu trả lời ngay bây giờ với thông tin để sử dụng công cụ tiện dụng này trong BeforeBuild (hoặc AfterBuild) thay vì xây dựng trước. Tuyệt vời đánh giá cao. – MemeDeveloper

4

Sử dụng @ ứng dụng giao diện điều khiển tiện dụng Vance ở trên, tôi đã sử dụng sau đây là một sự kiện 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> 

Điều này cực kỳ tiện lợi, vì tránh việc triển khai gây phiền nhiễu. Cảm ơn bạn đã chia sẻ Vance.

Tôi đã thêm TF.exe vào thư mục giải pháp Thư viện và điều này giúp, vì bây giờ tôi có thể xem các tệp edmx trước khi cố chỉnh sửa chúng, như một phần của bản dựng. Ngoài ra tôi đã thêm điều này với các điều kiện, do đó nó thiết lập đến năm 2005 để triển khai cho máy chủ và quay trở lại năm 2008 cho các cấu hình máy Sl. Cũng cần đề cập đến bạn cần thêm tệp SetEdmxSqlVersion.exe (và .pdb) thực tế vào thư mục Library (hoặc bất cứ nơi nào khác bạn muốn giữ các bit này).

Cảm ơn rất nhiều @Vance. Thật gọn gàng, đồ sộ tiết kiệm thời gian và giữ tôi builds hoàn toàn tự động và miễn phí đau :)

2

Vì lợi ích của những người gặp phải vấn đề tương tự nhưng đang sử dụng Mã Đầu tiên, hãy kiểm tra my answer here về làm thế nào để thay đổi ProviderManifestToken trong Mã đầu tiên. Nó liên quan đến việc tạo ra một thủ công DbModelBuilder và chuyển một cá thể DbProviderInfo (với mã thông báo thích hợp) khi gọi phương thức Build của người xây dựng mô hình.

+0

Tôi nghĩ rằng thiết lập 'Loại hệ thống phiên bản = SQL Server 2005' trong chuỗi kết nối cũng có thể làm việc – code4j

1

Đã có một vấn đề tương tự với 2012 so với năm 2008. Nó có thể được giải quyết với một sự kiện BeforeBuild sử dụng XmlPeek và 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> 

Nếu bạn không thích thay thế tự động, bạn chỉ có thể thay thế nhiệm vụ XmlPoke với một Lỗi bài tập.

+0

Điều này là tốt hơn nhiều so với sử dụng một thực thi bên ngoài, cho phép MSBuild để xử lý tất cả các fancy-ness nội bộ. Điều này tất cả có thể dễ dàng bị xâu chuỗi thông qua các nhiệm vụ mục tiêu trước khi xây dựng có điều kiện 'CallTarget' tùy thuộc vào các cấu hình publish/build. (EG chỉ thay đổi khi triển khai vào môi trường sql2005) – admalledd

0

Chúng tôi đã gặp lỗi này trên SQL2005 v.3, nơi chúng tôi không có nó trên SQL2005 v.4.

Thêm SQL2005 vào chuỗi kết nối đã khắc phục sự cố cụ thể của chúng tôi.

Chúng tôi chưa xác định lý do tại sao và không muốn sửa đổi mã để cung cấp mã thông báo như đã giải quyết ở trên (vấn đề được hiển thị trong khi triển khai).

Các vấn đề liên quan