11
votes

La comparaison des queues d'égalité retourne false

J'ai une requête avec la manière dont les dentètes sont comparées / stockées dans C #. Considérez le code suivant:

var createdDate = DateTime.Now;
using (cr = new LanguageDictionaryRepository(ds)) {
    cr.Add(new Sybrin10.Data.DTO.LanguageDictionary() {
        Active = true,
        CreatedDate = createdDate,
        CultureCode = cultureCode,
        Data = new System.Text.UTF8Encoding().GetBytes("Test")
    });
    cr.Save();

    var y = cr.FindBy(x => x.CultureCode == cultureCode && x.CreatedDate == createdDate).FirstOrDefault();
    Assert.IsNotNull(y);


6 commentaires

Êtes-vous sûr que les dates sont identiques? La comparaison prendra des heures / minutes / secondes / milli-secondes en compte.


C'est la chose, les valeurs de tick sont différentes, mais je ne sais pas pourquoi car ils proviennent tous deux de la même variable créée.


Désolé, j'ai supprimé mon commentaire accidentellement: / Combien les tiques diffèrent-elles? Est-ce une différence constante?


Par 117 avec X.CreateDaDate étant plus grande.


Ive Mise à jour ma réponse, fondamentalement 117 n'est rien parce qu'une coche est un dix-million d'une seconde.


Merci pour votre réponse, cela m'a donné beaucoup de détails.


3 Réponses :


0
votes

Je pense qu'il serait peut-être préférable d'utiliser DateTime.utcnow lorsque vous stockez les données, puis vous n'avez pas à vous soucier des problèmes de temps d'économie de jour, etc. Vous pouvez ensuite l'afficher comment vous voulez plus tard en utilisant la culture que vous utilisez. Choisissez.


0 commentaires

21
votes

Essayez d'utiliser DateTime.equals (x.createdDate, créatedDate) , cela pourrait aider.

Autre que cela, bon DateTime La comparaison est un sujet massivement compliqué avec des fuseaux horaires, des décalages, de l'UTC, de l'heure locale et de ce que. Je ne serais pas du tout surpris sur un simple == comparer entre deux dates apparemment identiques à renvoyer false.

Si la valeur diffère sur l'écriture et la lecture, vous pouvez être confronté à un problème DateTimeKind , où vous écrivez un denttitimekind.local < / Code> Dans la base de données, mais récupérer un DateTimeKind.unspecified .

L'autre option pourrait être (si la différence est suffisamment petite) que le champ DateTime de votre base de données n'est pas suffisamment significatif pour stocker la même quantité de millisecondes que le .NET DateTime < / code>:

Une seule tique représente cent nanosecondes ou un dix-million d'une seconde. Il y a 10 000 tiques dans un milliseconde.

Selon votre stockage de données, cela pourrait ne pas être aussi détaillé que ceci. Les valeurs DateTime ne proviennent pas de la même source, l'une est lue de la mémoire, l'autre est lue de la base de données.


3 commentaires

Dans ce cas, la représentation des chaînes des dates est-elle une option valide?


Si vous voulez simplement récupérer le disque que vous avez créé, voir Teleriks Comment: insérer des objets . Il va lire la clé primaire créée après l'enregistrement.


En fait, je vais créer une extension à la classe DateTime pour comparer sans ticks car je vois cela à nouveau. Merci pour la réponse, cela m'a donné beaucoup de clarté.



3
votes

sqlserver stocke un DateTime dans (environ) incréments de 3-millisecondes .

Les valeurs DateTime sont arrondies par incréments de 0,000, .003 ou 0,007 secondes

une demi-heure d'une date d'heure à travers la base de données pourrait donc être désactivée par quelques ms.

Donc, vous ne devez pas tester "exactement égal", mais pour "assez proche" xxx


3 commentaires

Je ne savais pas cela, merci de l'avoir souligné, j'avais évoqué mais votre échantillon de code n'est pas très pratique en réalité. Maintenant, si vous en faites une extension, maintenant nous parlons


Vous pouvez utiliser (x.createddateddateddatedDate) .Milliseconds <4 Si vous cherchez une notation plus courte.


@DDDW - Vous devrez ajouter un math.abs autour de lui, car vous pourriez obtenir des valeurs négatives de cette comparaison (qui sont bien sûr toujours <4)