144 votes

Entity Framework DateTime et UTC

est-il possible d'avoir Entity Framework (je suis en utilisant la Première Approche de Code avec CTP5 actuellement) stocker toutes les valeurs DateTime que l'UTC dans la base de données?

Ou est-il peut-être une façon de le spécifier dans la cartographie, par exemple dans celui-ci pour la last_login colonne:

modelBuilder.Entity<User>().Property(x => x.Id).HasColumnName("id");
modelBuilder.Entity<User>().Property(x => x.IsAdmin).HasColumnName("admin");
modelBuilder.Entity<User>().Property(x => x.IsEnabled).HasColumnName("enabled");
modelBuilder.Entity<User>().Property(x => x.PasswordHash).HasColumnName("password_hash");
modelBuilder.Entity<User>().Property(x => x.LastLogin).HasColumnName("last_login");

Merci

159voto

Matt Johnson Points 33433

Ici est une approche que vous pourriez envisager:

Tout d'abord, définissez cet attribut suivant:

[AttributeUsage(AttributeTargets.Property)]
public class DateTimeKindAttribute : Attribute
{
    private readonly DateTimeKind _kind;

    public DateTimeKindAttribute(DateTimeKind kind)
    {
        _kind = kind;
    }

    public DateTimeKind Kind
    {
        get { return _kind; }
    }

    public static void Apply(object entity)
    {
        if (entity == null)
            return;

        var properties = entity.GetType().GetProperties()
            .Where(x => x.PropertyType == typeof(DateTime) || x.PropertyType == typeof(DateTime?));

        foreach (var property in properties)
        {
            var attr = property.GetCustomAttribute<DateTimeKindAttribute>();
            if (attr == null)
                continue;

            var dt = property.PropertyType == typeof(DateTime?)
                ? (DateTime?) property.GetValue(entity)
                : (DateTime) property.GetValue(entity);

            if (dt == null)
                continue;

            property.SetValue(entity, DateTime.SpecifyKind(dt.Value, attr.Kind));
        }
    }
}

Maintenant, accrochez cet attribut à votre contexte EF:

public class MyContext : DbContext
{
    public DbSet<Foo> Foos { get; set; }

    public MyContext()
    {
        ((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized +=
            (sender, e) => DateTimeKindAttribute.Apply(e.Entity);
    }
}

Désormais DateTime ou DateTime? propriétés, vous pouvez appliquer cet attribut:

public class Foo
{
    public int Id { get; set; }

    [DateTimeKind(DateTimeKind.Utc)]
    public DateTime Bar { get; set; }
}

Dans ce lieu, chaque fois que Entity Framework charge d'une entité à partir de la base de données, il va mettre la DateTimeKind que vous spécifiez, telles que l'UTC.

Notez que ce n'est pas faire n'importe quoi lors de l'enregistrement. Vous devrez toujours avoir la valeur correctement converti à l'UTC avant d'essayer de le sauver. Mais il ne vous permet pas de définir le type lors de la récupération, ce qui lui permet d'être sérialisé que l'UTC, ou convertis en d'autres temps, les zones avec TimeZoneInfo.

6voto

Jon Points 4349

6voto

Vijay Points 66

Il n'y a aucun moyen de spécifier le DataTimeKind dans le Cadre de l'Entité. Vous pouvez décider de convertir les valeurs de date et heure utc avant de les stocker dans la base de données et de toujours assumer les données récupéré à partir de db que l'UTC. Mais les objets DateTime materalized pendant requête sera toujours "non spécifié". Vous pouvez également evalualte à l'aide de DateTimeOffset un objet de type DateTime.

4voto

michael.aird Points 218

Si vous êtes prudent de bien passer dans les dates UTC lorsque vous définissez les valeurs et tout ce qui vous intéresse est de s'assurer que le DateTimeKind est correctement réglé lorsque les entités sont extraites de la base de données, voir ma réponse ici: http://stackoverflow.com/a/9386364/279590

0voto

Brian Ball Points 6468

Est-il raisonnable de toujours utiliser l'UTC lorsque vous définissez la valeur de votre entité? Si vous êtes inquiet que quelqu'un pourrait oublier de faire cela, alors vous pouvez avoir votre poseurs de vos propriétés à le faire à chaque fois que la valeur est définie.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X