我首先使用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?
由于
答案 0 :(得分:3)
我以前遇到过这个问题,因为DateTime的实体框架标准是DateTime2字段,显然解决方法是将所有列更新到SQL Server数据库中的datetime2,但是datetime2数据类型仅在SQL Server 2008中引入,所以这里有一些尝试:
首先:确保如果SQL数据库中的DateTime字段可以为空,您的模型是否正在使用“DateTime?” (可以为空的日期时间)而不是“日期时间”。
第二:使用任何XML编辑器打开您的EDMX文件(Visual Studio应该工作)并将ProviderManifestToken
的值更改为ProviderManifestToken="2005"
,这应该确保SQL Server 2005的兼容性。
适用于.edmx文件,但Code First更改将更具挑战性,并且将取决于您的实体框架版本,因此Microsoft建议您尝试在OnModelCreating方法上指定列类型,如下例所示:
modelBuilder.Entity<Blog>().Property(t => t.CreatedOn).HasColumnName("CreatedOn").HasColumnType("date");
尝试使用ColumnType的值,直到达到目标为止。
如果您仍想更改ProviderManifestToken
值:
E.F。 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
{
}
(来源:How to configure ProviderManifestToken for EF Code First)
E.F。 5岁及以上:阅读这篇文章,轻松澄清:http://blog.oneunicorn.com/2012/04/21/code-first-building-blocks/
希望有所帮助。
答案 1 :(得分:2)
令人讨厌的是,费利普的建议没有用,虽然我看不出有什么理由不这样做。
我设法破解了我自己的解决方案。并不完全满意,但我们正试图让客户端升级到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());
}
我会密切注意这一点,以确保它的行为。
答案 2 :(得分:0)
我通过删除数据库并在包管理器控制台中再次运行update-database命令来解决它。但不适合生产环境。