使用 SQL Server 2008 和 SQL Server 2005 以及日期时间

发布于 2024-07-09 12:50:48 字数 256 浏览 9 评论 0原文

我已经根据 2008 年数据库构建了一个实体框架模型。 2008 年数据库一切正常。 当我尝试更新 2005 数据库上的实体时,出现此错误。

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

我在构建数据库时特别没有使用任何 2008 年的功能。 我在代码中找不到任何对 datetime2 的引用。 并且,是的,该列在数据库中定义为“日期时间”。

I've built a entity framework model against a 2008 database. All works ok against the 2008 database. When I try to update the entity on a 2005 database I get this error.

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

I specifically did not use any 2008 features when I built the database. I can't find any reference to datetime2 in the code. And, yes the column is defined as "datetime" in the database.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

淡水深流 2024-07-16 12:50:48

快速谷歌将我指向看起来像解决方案

在文件编辑器中打开 EDMX(或在 Visual Studio 中“打开方式...”并选择 XML 编辑器)。 在顶部,您将找到存储模型,它有一个属性 ProviderManifestToken。 它的值应该是 2008。将其更改为 2005,重新编译,一切正常。

注意:每次从数据库更新模型时都必须执行此操作。

A quick google points me to what looks like the solution.

Open your EDMX in a file editor (or “open with…” in Visual Studio and select XML Editor). At the top you will find the storage model and it has an attribute ProviderManifestToken. This has should have the value 2008. Change that to 2005, recompile and everything works.

NOTE: You'll have to do this every time you update the model from database.

久夏青 2024-07-16 12:50:48

线路快速查看:

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

Quick view of line:

<Schema Namespace="Foobar.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005" >
々眼睛长脚气 2024-07-16 12:50:48

这是非常令人沮丧的,我很惊讶微软决定不这样做,这样你就可以针对给定的 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);
            }
        }
    }
}

This is very frustrating and I am surprised MS decided not to make it so you could target a given SQL version. To make sure we are targeting 2005 I wrote a simple console app and call it in a PreBuild step.

The prebuild step looks like this:

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

The code is here:

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);
            }
        }
    }
}
太阳公公是暖光 2024-07-16 12:50:48

使用上面@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,将开发计算机 sln 配置设置为 2008。 还要提一下,您需要将实际的 SetEdmxSqlVersion.exe(和 .pdb)文件添加到 Library 文件夹(或您想要保留这些位的其他位置)。

非常感谢@Vance。非常简洁,节省大量时间,并使我的构建完全自动化且无痛:)

Using @Vance's handy console app above, I used the following as a BeforeBuild event

<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>

This is super handy, as avoids annoying redeployment. Thanks for sharing Vance.

I've added TF.exe to the Library solution folder and this helps, as I can now check out the edmx files before trying to edit them, as part of the build. Also I have added this with conditions, so that it sets to 2005 for deployments to the server and back to 2008 for the Dev machine sln configurations. Also to mention you need to add the actual SetEdmxSqlVersion.exe (and .pdb) file(s) to the Library folder (or wherever else you want to keep these bits).

Thanks very much @Vance. Really neat, massive time saver and keeps my builds totally automated and pain free :)

死开点丶别碍眼 2024-07-16 12:50:48

2012 年与 2008 年有类似的问题。它可以通过使用 XmlPeek 和 XmlPoke 的 BeforeBuild 事件来解决:

   <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 任务替换为 Error 任务。

Had a similar problem with 2012 vs. 2008. It can be solved with a BeforeBuild event using XmlPeek and 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>

If you dislike automated replacement, you can simply replace the XmlPoke task with an Error task.

街道布景 2024-07-16 12:50:48

For the benefit of people who encounter the same issue but are using Code First, check out my answer here about how to change the ProviderManifestToken in Code First. It involves creating a DbModelBuilder manually and passing a DbProviderInfo instance (with the appropriate token) when calling the model builder's Build method.

夜司空 2024-07-16 12:50:48

对我来说更好的解决方案是在设计模式下和上下文菜单“从数据库更新模型...”中打开 edmx,而不是手动编辑 EDMX 文件。
当然,无论这适合您,您都必须指向正确的 SQL 版本。

Better solution to me is instead of manually editing EDMX file is just open edmx in design mode and in context menu "Update Model from Database...".
You have to be pointing to right SQL version of course whatever this is for you.

九歌凝 2024-07-16 12:50:48

我们在 SQL2005 v.3 上遇到此错误,而在 SQL2005 v.4 上则没有此错误。

将 SQL2005 添加到连接字符串解决了我们的特定问题。

我们尚未确定原因,并且不想修改代码以提供上面解决的令牌(部署期间出现的问题)。

We had this error on SQL2005 v.3, where we did not have it on SQL2005 v.4.

Adding SQL2005 to the connection string fixed our specific problem.

We haven't identified why yet, and did not want to modify code to provide the token as solved above (issue manifested during deployment).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文