我正在使用一个具有以下类时间的api。
public class CRTime
{
public DateTime? datetime { get; set; }
public string timezone { get; set; }
}
我想将其转换为单个DateTime字段。
这是返回给我的完整对象的示例,以及我如何尝试计算将存储在数据库中的DateTime字段。
public class ReturnObject
{
[NotMapped]
// This comes from the api, but is not synced to database
public CRTime CRCreated { get; set; }
// this is stored in our db, should be calculated from CRCreated
public DateTime? CreatedDB { get
{
var val = (CRCreated != null) ? CRCreated.datetime : null;
return val;
}
private set { }
}
// other fields go here
}
这在创建记录时非常完美,但是当我尝试使用Entity.Migration框架和AddOrUpdate更新记录时,更新将覆盖该值并将其始终设置为NULL。
创建服务器端计算的列然后将其同步到数据库的最佳解决方案是什么。
旁注:我正在使用NewtonSoft Json将对象反序列化为我的实体框架对象,然后将其传递给Entity Framework AddOrUpdate。
最佳答案
这是因为AddOrUpdate
的一个令人困惑的怪癖。AddOrUpdate
显然确定一个实体是新的还是现有的。它通过按数据库的主键或您可以指定的某些键在数据库中查询实体来完成此操作。现在可以发生两件事:
它在数据库中找不到实体;您的实体对象被标记为Added
。
它确实找到了一个实体,但是与您期望的实体对象仍然是Detached
相反!找到的实体保持隐藏状态,这是对象EF最后更新的对象。它将值从您自己的实体复制到该实体,这可能会将隐藏的实体标记为Modified
。
显然,通过此空的setter,从数据库中获取CreatedDB
时将始终为null
。对于EF,CRCreated
不存在。它可能会从您的对象中读取一个CreatedDB
值,但是空的setter再次阻止了它被复制到隐藏的对象中,并以null
的形式进行了更新。
您必须决定如何解决此问题。最好的方法可能是使setter实际修改(或创建)CRCreated
实例。
或者,您可以取消AddOrUpdate
并尝试自己查找现有对象。如果找到它,它就不再隐藏了,因此您可以随便使用它。
关于c# - Entity Framework 服务器端计算值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37643563/