c# - 为什么 C# EF Core 删除使用块之间的值?
问题描述
编辑:答案很简单,我错过了属性 {get; 在我的时间戳上设置},因此 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; }
}
这里是它被添加到 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()
行之后立即断点,我可以看到仪表已添加到 Meters DbSet 并且它们具有正确的 DateTime 时间戳(即[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 时有所帮助。我意识到我没有告诉 InMemoryDatabase 如何处理空值,但我也从来没有给它空值,那么给出了什么?
是否需要设置一些设置以防止 InMemoryDatabase 在设置值后触摸它们?
解决方案
该问题与 InMemory 数据库没有任何共同之处。
原因是您的实体中的一个小错误:
public DateTime Timestamp;
Timestamp
是一个字段,因此没有映射也没有存储。在使用用于添加实体的上下文时,更改跟踪器会返回原始实例,这就是您看到已设置值的原因。但是一旦你创建了一个新的上下文,查询就会创建新的对象,当然未映射的字段也有默认值。
只需使其成为财产
public DateTime Timestamp { get; set; }
推荐阅读
- reactjs - 为什么是 。作为参数传递给没有 -- 分隔符的 npm?
- node.js - 如何限制使用 Amazon S3 presignedUrl 向当前用户发布文件
- designer - 在我的系统中的业务对象 Universe 设计器工具中所做的更改不会反映在其他用户的业务对象中
- html - React 获取组件实例的属性
- python - 如何得出结论?
- stm32 - mpu6050&dmp和stm32h7的使用
- apache-kafka-mirrormaker - 使用 MirrorMaker2 重新同步偏移量
- c# - 使用 VMSS 代理进行自动化测试
- google-chrome-extension - 当我开始使用 chrome.tabCapture.capture(
- google-sheets-formula - 我正在尝试将大型(14k)数据从网页收集到我的谷歌表格。IMPORTXML 返回我“超过数据量”的消息。我怎么能通过它?