我正在消耗一个具有以下课程时间的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。
答案 0 :(得分:2)
这是因为AddOrUpdate
的一个相当混乱的怪癖。
AddOrUpdate
确定实体是新的还是现有的。它通过主键或您可以指定的某个键查询实体的数据库来实现。现在可能发生两件事:
Added
。Detached
!找到的实体仍然是隐藏的,这是EF最终更新的对象。它会将您自己实体的值复制到它,这可能会将隐藏的实体标记为Modified
。显然,通过这个空的setter,CreatedDB
在从数据库中取出时始终为null
。对于EF,CRCreated
不存在。它可能会从您的对象中读取CreatedDB
值,但空的setter会阻止它被复制到隐藏对象,并且会更新为null
。
你必须决定如何解决这个问题。可能最好的方法是让setter实际修改(或创建)CRCreated
实例。
或者,您可以取消AddOrUpdate
并尝试自己查找现有对象。如果你发现它,它就不会被隐藏了,所以你可以随心所欲地使用它。
答案 1 :(得分:1)
从Db读取后我希望它为NULL。 private set;
当然很奇怪,阻碍了EF的正常运作。
当你能够使用DateTimeOffset但在目前的情况下,你可以帮助自己:
您的财产可能会按逻辑'计算'但是对于数据库,它应该被视为正常的读/写属性。