2

Сначала я подключаюсь к базе данных, используя базу данных EF. Поэтому мои модели автогенерируются.Force DateTime с базой данных Entity Framework Сначала

Когда я обновляю запись, мои 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 при записи в базу данных?

Благодаря

ответ

3

Я имел эту проблему в прошлом, как Entity Framework стандарт для DateTime этого поля Datetime2, то, очевидно, обходной путь, чтобы обновить все столбцы в datetime2 в базе данных SQL Server, однако datetime2 типа данных был только в SQL Server 2008, так что вот несколько вещей, которые можно попробовать:

Во-первых: убедитесь, что , если поле DateTime в вашей базе данных SQL имеет значение NULL, ваша модель использует «DateTime?». (nullable datetime) вместо «DateTime».

Во-вторых: откройте свой файл EDMX любым редактором XML (Visual Studio должен работать) и измените значение вашего ProviderManifestToken на ProviderManifestToken="2005", это должно обеспечить совместимость с SQL Server 2005.

Это работает с .edmx-файлами, но с изменением кода First будет немного сложнее и будет зависеть от вашей версии Framework Entity Framework, поэтому 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 
{ 
} 

(источник: How to configure ProviderManifestToken for EF Code First)

E .F. 5 и старше: прочитайте этот пост, который легко прояснит его: http://blog.oneunicorn.com/2012/04/21/code-first-building-blocks/

Надеюсь, что это поможет.

+1

Следует отметить, что редактирование файла 'edmx' напрямую будет перезаписано при следующей проверке модели. Так что это не должно быть использовано. Мне нравится подход использования 'DbConfiguration' – Hopeless

+0

Это выглядит многообещающим. К сожалению, пользовательский класс DbConfiguration, кажется, полностью игнорируется. Я использую EF 6.1.3 –

+0

Дэвид, вы попробовали указать тип столбца в методе OnModelCreating? –

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()); 
    } 

Я буду держать хорошие часы на это убедитесь, что он ведет себя.

0

Я решаю его, удалив базу данных и снова запустив команду update-database в консоли диспетчера пакетов. Однако не подходит для производственной среды.

Смежные вопросы