Почему C # EF Core удаляет значения между использованием блоков? - PullRequest
0 голосов
/ 28 февраля 2019

РЕДАКТИРОВАТЬ: Ответ прост, я пропустил свойство {получить;set} на моей метке времени, и поэтому EF Core игнорирует сопоставление.Но продолжайте читать, если вы чувствуете такую ​​склонность.

Я использую InMemoryDatabase C # EF Core для выполнения модульных тестов для моего приложения.Однако для определенного набора тестов у меня возникает странная ошибка, когда DateTime на некоторых объектах сбрасывается на значение по умолчанию [1/1/0001 12:00:00 AM], когда я ссылаюсь на них позже.
Это объект POCO, который создается и добавляется вконтекст:

    public class Meter
    {
        [Key]
        public long Id { get; set; }
        public DateTime Timestamp;
        public int Change { get; set; }
    }

И вот где он добавляется в DbContext:

options = new DbContextOptionsBuilder().UseInMemoryDatabase("TestDB");
using (var db = new CustomContext(options))
{
    for (int i = 0; i < 10; i++)
    {
        var meter = new Meter {Timestamp = new DateTime(2019, 1, 20), Change = i};
        db.Meters.Add(meter);
    }
    db.SaveChanges();
}

Если я остановлю точку во время теста сразу после строки db.SaveChanges(), я могу видеть, чтометры были добавлены в DbSet метров и имеют правильную дату и время для метки времени (т. е. [1/20/2019 12:00:00 AM]).Тем не менее, когда я ссылаюсь на контекст позже так:

using (var db = new CustomContext(options))  //Same options as I used before
{
    var times = db.Meters.Select(m => m.Timestamp);
}

Если я остановлюсь на этой строке, каждому метру в db.Meters будет присвоено начальное время по умолчанию, равное [1/1/0001 12:00:00 AM].Тем не менее, свойство Change по-прежнему сохраняет первоначальное значение int, как и ожидалось.

В настоящее время это поражает воображение, и я попробовал несколько вариантов для устранения проблемы.Я попытался добавить промежуточный шаг между добавлением и последующим запросом, где я повторял бы каждый счетчик и обновлял метку времени, сохранял изменения, а затем выполнял запрос - и все равно не получилось!Я попытался DateTime? Timestamp, и это просто устанавливает время на ноль, я попытался также добавить [DatabaseGenerated(DatabaseGeneratedOption.Identity)], поскольку это помогло при использовании моей базы данных Npgsql и указание ей использовать CURRENT_TIMESTAMP, если Timestamp когда-либо установлен на ноль.Я понимаю, что я не сказал InMemoryDatabase, что делать с нулевыми значениями, но я также никогда не давал ему нулевые значения, так что же дает?

Есть ли какие-то настройки, которые мне нужно установить, чтобы сохранить InMemoryDatabase откасаясь значений после того, как они были установлены?

1 Ответ

0 голосов
/ 28 февраля 2019

Проблема не имеет ничего общего с базой данных InMemory.

Причина - тривиальная ошибка в вашей сущности:

public DateTime Timestamp;

Timestamp - это поле , поэтому не отображается и не сохраняется.При работе с контекстом, используемым для добавления сущностей, трекер изменений возвращает исходные экземпляры, поэтому вы видите установленные вами значения.Но как только вы создаете новый контекст, запрос создает новые объекты, и, конечно же, неотображаемые поля имеют значения по умолчанию.

Просто сделайте это свойство

public DateTime Timestamp { get; set; }
...