Використання SQL Server 2008 та SQL Server 2005 та часу дати


118

Я створив модель фреймворку сутності на базі даних 2008 року. Все працює нормально проти бази даних 2008 року. Коли я намагаюся оновити об'єкт на базі даних 2005 року, я отримую цю помилку.

Використовувана версія SQL Server не підтримує тип даних 'datetime2

Я спеціально не використовував жодних функцій 2008 року, коли будував базу даних. Я не можу знайти в коді жодної посилання на datetime2. І так, стовпець визначається як "дата часу" в базі даних.

Відповіді:


189

Швидкий google вказує мені на те, що схоже на рішення .

Відкрийте свій EDMX у редакторі файлів (або "відкрити за допомогою ..." у Visual Studio та виберіть XML Editor). Угорі ви знайдете модель пам’яті, в якій є атрибут ProviderManifestToken. Це повинно мати значення 2008. Змініть це до 2005 року, перекомпілюйте і все працює.

ПРИМІТКА. Це потрібно буде робити щоразу, коли ви оновлюєте модель з бази даних.


2
Я проголосував це помилково, але це тепер не можу зробити те, що я насправді хотів, а це проголосувати! Дякуємо, що знайшли проблему. Якщо я правильно розумію, чи змінюється значення з 2005 по 2008 рік через оновлення моделі з бази даних, де БД є БД SQL 2008? У моєму середовищі машина мого розробника має SQL 2008, але тестове середовище має 2005 рік (який також є виробництво). Поки ми не перейдемо на 2008 рік, чи я маю рацію припускати, що це буде продовжуватися?
jamiebarrow

Я загалом встановив це на 2005 рік, що є виробничою базою даних; Я використовую 2008 рік для розробки. 2008 рік сумісний назад, тому проблем немає. Також це потрібно змінити назад після оновлення / генерування. Я завжди підтверджую це під час перевірки в EDMX після гіркого досвіду.
Річард Гаррісон

це виправлення не працює для мене ?? forums.asp.net/p/1770522/4838628.aspx/…
король

Якщо це відбувається в LightSwitch, перегляньте мій пост у блозі, де пояснюється, як це виправити у файлі lsml (оскільки у LS немає прямого доступу до файлу edmx): lightswitchcentral.net.au/Blog/tabid/83/EntryId/27/ …
Ян Дюран

Це єдине рішення, але ви повинні знати, що вам потрібно робити це кожного разу, коли ви змінюєте edmx, оскільки він повернеться
Дейв Хоган

11

Швидкий перегляд рядка:

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

10

Це дуже засмучує, і я здивований, що 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 дякую дуже, ідеально. Трохи повільно, оскільки у мене є три файли 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 року для конфігурацій машинного сценарію Dev. Також потрібно згадати, що вам потрібно додати фактичні файли SetEdmxSqlVersion.exe (та .pdb) до папки «Бібліотека» (або де б ви не хотіли зберегти ці біти).

Дуже дякую @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 на помилку.


Це набагато краще, ніж використання зовнішнього виконуваного файлу, дозволяє MSBuild внутрішньо обробляти всі фантазії. Це все можна легко пов'язати за допомогою CallTargetумовних цільових завдань попереднього збирання залежно від конфігурацій публікації / складання. (EG змінюється лише під час розгортання в середовищі sql2005)
оголошено

1

На користь людям, які стикаються з тією ж проблемою, але користуються кодом спочатку , ознайомтеся з моєю відповіддю про те, як змінити ProviderManifestTokenкод у першу чергу. Він передбачає створення DbModelBuilderвручну та передачу DbProviderInfoекземпляра (з відповідним маркером) під час виклику Buildметоду конструктора моделі .


Я думаю, що набір Type System Version=SQL Server 2005у рядку з'єднання також може працювати
code4j

0

Для мене краще рішення - замість того, щоб вручну редагувати файл EDMX - це просто відкрити edmx в режимі дизайну та в контекстному меню "Оновити модель з бази даних ...". Ви повинні вказувати на правильну версію SQL, звичайно, що б це не було для вас.


1
Я думаю, що це проблема ОП - він розробив місцевий SQL 2008, але потім розгорнув його до SQL 2005.
StuartLC

Це працює, якщо у вас немає доступу до екземпляра SQL 2005.
Дарсі

1
Величезним недоліком є ​​те, що це крок вручну, і, таким чином, буде забутий.
Jowen

0

У нас була помилка на SQL2005 v.3, де її у SQL2005 v.4 не було.

Додавання SQL2005 до рядка з'єднання вирішило нашу конкретну проблему.

Ми ще не визначили чому, і не хотіли змінювати код, щоб надавати маркер, як вирішено вище (проблема, виявлена ​​під час розгортання).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.