Я построил модель фреймворка сущности на основе базы данных 2008 года. Все работает нормально с базой данных 2008 года. Когда я пытаюсь обновить объект в базе данных 2005 года, я получаю эту ошибку.
The version of SQL Server in use does not support datatype 'datetime2
Я специально не использовал какие-либо функции 2008 года при создании базы данных. Я не могу найти в коде ссылки на datetime2. И, да, столбец в базе данных определен как «datetime».





Быстрый поиск в Google указывает мне на то, что выглядит как решение.
Откройте EDMX в редакторе файлов (или «откройте с…» в Visual Studio и выберите XML Editor). Вверху вы найдете модель хранилища с атрибутом ProviderManifestToken. Он должен иметь значение 2008. Измените это на 2005, перекомпилируйте, и все заработает.
ПРИМЕЧАНИЕ. Вам придется делать это каждый раз, когда вы обновляете модель из базы данных.
Я обычно устанавливаю это на 2005, которая является производственной базой данных; Я использую 2008 год для разработки. 2008 имеет обратную совместимость, так что никаких проблем. Также это должно быть изменено обратно после обновления / генерации. Я всегда подтверждаю это, проверяя EDMX после горького опыта.
это исправление не работает для меня ?? форумы.asp.net/p/1770522/4838628.aspx/…
Если это происходит в LightSwitch, см. Сообщение в моем блоге, в котором объясняется, как исправить это в файле lsml (поскольку в LS нет прямого доступа к файлу edmx): lightswitchcentral.net.au/Blog/tabid/83/EntryId/27/…
Это единственное решение, но вы должны знать, что вам нужно делать это каждый раз, когда вы изменяете edmx, так как он сам вернется.
С обновлениями EF6 (интерецепторы и т. д.) Есть лучшие решения, чем это было разработано (те, которые менее склонны к случайному забыванию при каждом обновлении EDMX). Итак, сначала подход к базе данных, но где мы, возможно, можем перехватить загрузку модели и программно указать версию sql для использования?
Это похоже на то, что, я думаю, было бы достижимо, если бы мы знали, какие кнопки нужно нажимать ... stackoverflow.com/questions/33282739/…
Быстрый просмотр линии:
<Schema Namespace = "Foobar.Store" Alias = "Self" Provider = "System.Data.SqlClient" ProviderManifestToken = "2005" >
Лучшее решение для меня - вместо того, чтобы вручную редактировать файл EDMX, просто откройте edmx в режиме разработки и в контекстном меню «Обновить модель из базы данных ...». Конечно, вы должны указывать на правильную версию SQL, что бы это ни было для вас.
Я думаю, что это проблема OP - он разработал для локального SQL 2008, но затем развернул на SQL 2005.
Это работает, если у вас нет доступа к экземпляру SQL 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, спасибо большое, отлично. Немного медленно, так как у меня есть три файла edmx, которые мне нужно изменить, поэтому я могу добавить конфигурацию решения, чтобы вернуться после развертывания, и удалить ее из обычной сборки. Сейчас опубликую ответ с информацией об использовании этого удобного инструмента в BeforeBuild (или AfterBuild) вместо предварительной сборки. Очень ценится.
Используя удобное консольное приложение @ 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>
Это очень удобно, так как позволяет избежать утомительного повторного развертывания. Спасибо, что поделились Вэнсом.
Я добавил TF.exe в папку решения библиотеки, и это помогает, так как теперь я могу проверить файлы edmx, прежде чем пытаться редактировать их, как часть сборки. Также я добавил это с условиями, так что он установлен на 2005 год для развертывания на сервере и обратно на 2008 год для конфигураций sln машины Dev. Также, чтобы упомянуть, вам необходимо добавить фактический файл (ы) SetEdmxSqlVersion.exe (и .pdb) в папку библиотеки (или в другое место, где вы хотите сохранить эти биты).
Большое спасибо @Vance. Действительно аккуратно, значительно экономит время и делает мои сборки полностью автоматизированными и безболезненными :)
Для тех, кто сталкивается с той же проблемой, но использует Сначала код, ознакомьтесь с мой ответ здесь о том, как изменить ProviderManifestToken в Code First. Он включает создание DbModelBuilder вручную и передачу экземпляра DbProviderInfo (с соответствующим токеном) при вызове метода Build построителя модели.
Я думаю, что установка Type System Version=SQL Server 2005 в строке подключения также может работать
Была аналогичная проблема с 2012 по сравнению с 2008 годом. Ее можно решить с помощью события BeforeBuild, используя XmlPeek и XmlPoke:
<Target Name = "BeforeBuild">
<XmlPeek XmlInputPath = "$(ProjectDir)MyModel.edmx"
Namespaces = "<Namespace Prefix='edmx' Uri='http://schemas.microsoft.com/ado/2009/11/edmx'/><Namespace Prefix='ssdl' Uri='http://schemas.microsoft.com/ado/2009/11/edm/ssdl'/>"
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 = "<Namespace Prefix='edmx' Uri='http://schemas.microsoft.com/ado/2009/11/edmx'/><Namespace Prefix='ssdl' Uri='http://schemas.microsoft.com/ado/2009/11/edm/ssdl'/>"
Query = "/edmx:Edmx/edmx:Runtime/edmx:StorageModels/ssdl:Schema/@ProviderManifestToken"
Value = "2008">
</XmlPoke>
</Target>
Если вам не нравится автоматическая замена, вы можете просто заменить задачу XmlPoke задачей с ошибкой.
Это намного лучше, чем использование внешнего исполняемого файла, позволяет MSBuild обрабатывать все причуды изнутри. Все это можно легко связать с помощью условных целевых задач предварительной сборки CallTarget в зависимости от конфигураций публикации / сборки. (EG изменяется только при развертывании в среде sql2005)
У нас была эта ошибка на SQL2005 v.3, где у нас ее не было на SQL2005 v.4.
Добавление SQL2005 в строку подключения устранило нашу конкретную проблему.
Мы еще не определили, почему, и не хотели изменять код для предоставления токена, как было решено выше (проблема проявляется во время развертывания).
Я по ошибке проголосовал за это, отменил это, но теперь не могу сделать то, что действительно хотел, а именно проголосовать за это! Спасибо, что нашли проблему. Если я правильно понимаю, изменилось ли значение с 2005 на 2008 год из-за обновления модели из базы данных, где база данных - это база данных SQL 2008? В моей среде на моей машине разработчика установлен SQL 2008, но в тестовой среде - 2005 (в производственной среде тоже). Правильно ли я предполагаю, что это будет продолжаться до тех пор, пока мы не перейдем к 2008 году?