log*_*s16 2 c# entity-framework-core ef-core-2.2
编辑:答案很简单,我错过了财产{get; 在我的Timestamp上设置},因此EF Core会忽略映射.但如果你有这种倾向,请继续阅读.
我正在使用C#EF Core的InMemoryDatabase为我的应用程序进行单元测试.但是,对于一组特定的测试,我有一个奇怪的错误,[1/1/0001 12:00:00 AM]当我稍后引用它们时,某些实体上的DateTime被重置为默认值.
这是正在创建并添加到上下文的POCO对象:
public class Meter
{
[Key]
public long Id { get; set; }
public DateTime Timestamp;
public int Change { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这里是它添加到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();
}
Run Code Online (Sandbox Code Playgroud)
如果我在测试过程中的断点db.SaveChanges(),我可以看到米已经添加到Meters DbSet并且它们具有正确的TimeTime用于时间戳(即[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);
}
Run Code Online (Sandbox Code Playgroud)
如果我在此行断点,则db.Meters中的每个仪表都已设置为默认的开始日期时间[1/1/0001 12:00:00 AM].但是,该Change属性仍按预期保持原始int值.
这是我的想法,我已经尝试了几个选项来纠正这个问题.我尝试在添加和查询之间添加一个中间步骤,在那里我将迭代每个仪表并更新时间戳,保存更改,然后再查询 - 它仍然失败!我试过DateTime? Timestamp,只是将时间设置为null,我尝试也添加,[DatabaseGenerated(DatabaseGeneratedOption.Identity)]因为这有助于使用我的Npgsql数据库并告诉它使用CURRENT_TIMESTAMP如果Timestamp被设置为null.我意识到我没有告诉InMemoryDatabase如何处理空值,但我也从未给它赋值空值,那么是什么给出了?
是否需要设置一些设置以防止InMemoryDatabase在设置后触摸值?
该问题与InMemory数据库没有任何共同之处.
原因是你的实体犯了一个微不足道的错误:
public DateTime Timestamp;
Run Code Online (Sandbox Code Playgroud)
Timestamp是一个字段,因此没有映射,也没有存储.在使用用于添加实体的上下文时,更改跟踪器返回原始实例,这就是您查看已设置的值的原因.但是一旦创建了新的上下文,查询就会创建新对象,当然未映射的字段也会有默认值.
简单地做它的财产
public DateTime Timestamp { get; set; }
Run Code Online (Sandbox Code Playgroud)