2

我首先使用 EF 数据库连接到数据库。因此我的模型是自动生成的。

当我更新记录时,我的 DateTimes 被写为 SQL 类型 DateTime2。生产服务器是 SQL Server 2005(请不要评论),因此更新失败,因为不支持 DateTime2。

我已经尝试按照http://www.asp.net/mvc/overview/getting-started/database-first-development/enhancing-data-validation为我的模型创建一个元数据类,并用 [Column( DbType = "datetime")],但要么我没有正确遵循说明,要么我走错了路。

写入数据库时​​如何让 EF 数据库首先使用 DateTime?

谢谢

4

3 回答 3

3

令人讨厌的是,费利佩的建议没有奏效,尽管我看不出有什么理由不应该这样做。

我设法破解了我自己的解决方案。对此并不完全满意,但我们正在尝试让客户端升级到 SQL Server 2014,因此它不是永久性的。欢迎评论...

首先我创建了这个类:

internal sealed class MyCommandInterceptor : IDbCommandInterceptor
{
    public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
    }

    public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
        ChangeDateTime2ToDateTimeForSqlServer2005Compatibility(command);
    }

    public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
    }

    public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        ChangeDateTime2ToDateTimeForSqlServer2005Compatibility(command);
    }

    public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
    }

    public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
        ChangeDateTime2ToDateTimeForSqlServer2005Compatibility(command);
    }

    /// <summary>
    /// Changes parameters of type datetime2 to datetime for SQL server2005 compatibility.
    /// </summary>
    /// <param name="command">The command.</param>
    private void ChangeDateTime2ToDateTimeForSqlServer2005Compatibility(DbCommand command)
    {
        foreach (DbParameter param in command.Parameters)
        {
            if (param.DbType == System.Data.DbType.DateTime2)
            {
                param.DbType = System.Data.DbType.DateTime;
            }
        }
    }
}

然后我在我的 DbContext 派生类中使用静态构造函数激活它:

    static MyDbContext()
    {
        // The command interceptor changes DateTime2 data types to DateTime for SQL Server 2005 compatibility.
        DbInterception.Add(new MyCommandInterceptor());
    }

我将密切关注这一点,以确保它的行为。

于 2015-09-25T10:27:02.917 回答
3

我过去遇到过这个问题,因为 DateTime 的实体框架标准是 DateTime2 字段,显然的解决方法是将 SQL Server 数据库中的所有列更新为 datetime2,但是 datetime2 数据类型仅在 SQL Server 2008 中引入,所以在这里有几件事可以尝试:

首先:确保如果 SQL 数据库中的 DateTime 字段为 nullable,则您的模型正在使用“DateTime?” (可为空的日期时间)而不是“日期时间”。

第二:使用任何 XML 编辑器(Visual Studio 应该可以)打开您的 EDMX 文件并将您的值更改ProviderManifestTokenProviderManifestToken="2005",这应该确保 SQL Server 2005 兼容性。

这适用于 .edmx 文件,但使用 Code First 更改将更具挑战性,并且取决于您的实体框架版本,因此 Microsoft 建议尝试在 OnModelCreating 方法中指定您的列类型,如下例所示:

modelBuilder.Entity<Blog>().Property(t => t.CreatedOn).HasColumnName("CreatedOn").HasColumnType("date");

尝试使用 ColumnType 的值,直到达到目标。

如果您仍想更改您的ProviderManifestToken值:

EF 6:您可以为您的 DbContext 创建配置,基本上是这样的类:

/// <summary>
/// A configuration class for SQL Server that specifies SQL 2005 compatability.
/// </summary>
internal sealed class EntityFrameworkDbConfiguration : DbConfiguration
{
    /// <summary>
    /// The provider manifest token to use for SQL Server.
    /// </summary>
    private const string SqlServerManifestToken = @"2005";

    /// <summary>
    /// Initializes a new instance of the <see cref="EntityFrameworkDbConfiguration"/> class.
    /// </summary>
    public EntityFrameworkDbConfiguration()
    {
        this.AddDependencyResolver(new SingletonDependencyResolver<IManifestTokenResolver>(new ManifestTokenService()));
    }

    /// <inheritdoc />
    private sealed class ManifestTokenService : IManifestTokenResolver
    {
        /// <summary>
        /// The default token resolver.
        /// </summary>
        private static readonly IManifestTokenResolver DefaultManifestTokenResolver = new DefaultManifestTokenResolver();

        /// <inheritdoc />
        public string ResolveManifestToken(DbConnection connection)
        {
            if (connection is SqlConnection)
            {
                return SqlServerManifestToken;
            }

            return DefaultManifestTokenResolver.ResolveManifestToken(connection);
        }
    }
}

用法:

DbConfigurationType(typeof(EntityFrameworkDbConfiguration))]
public class MyContextContext : DbContext
{
}

(来源:如何为 EF Code First 配置 ProviderManifestToken

EF 5 及更早版本:阅读这篇文章可以轻松阐明它:http ://blog.oneunicorn.com/2012/04/21/code-first-building-blocks/

希望有帮助。

于 2015-09-24T15:44:45.287 回答
0

我通过删除数据库并在包管理器控制台中再次运行 update-database 命令来解决它。但不适合生产环境。

于 2015-10-26T03:35:12.020 回答