C# 实体框架服务器端计算值

C# 实体框架服务器端计算值,c#,asp.net,.net,entity-framework,entity-framework-6,C#,Asp.net,.net,Entity Framework,Entity Framework 6,我正在使用一个具有以下类的api public class CRTime { public DateTime? datetime { get; set; } public string timezone { get; set; } } 我想把它转换成一个DateTime字段 下面是一个返回给我的完整对象的示例,以及我如何尝试计算将存储在数据库中的DateTime字段 public class ReturnObject { [NotMapped] // This

我正在使用一个具有以下类的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 framework和AddOrUpdate更新记录时,更新会覆盖该值并始终将其设置为NULL

创建服务器端计算列并同步到数据库的最佳解决方案是什么

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
}

旁注:我正在使用NewtonSoft Json将该对象反序列化为我的entity framework对象,然后将其传递给entity framework AddOrUpdate。

我希望在您从数据库中读取该对象后该对象为空。
私有集
当然很奇怪,阻碍了EF的正常工作

当您能够使用DateTimeOffset时,您可以帮自己一个大忙,但在当前情况下:


您的属性可能在逻辑上是“计算”的,但对于数据库,它应该作为正常的读/写属性来处理和实现

这是因为
AddOrUpdate
有一个相当令人困惑的怪癖

AddOrUpdate
确定实体是新的还是现有的。它通过查询数据库中实体的主键或您可以指定的某个键来实现这一点。现在可能发生两件事:

  • 在数据库中找不到实体;您的实体对象被标记为添加的
  • 它确实找到了一个实体,但与您期望的相反,您的实体对象仍然是分离的!找到的实体保持隐藏,这是最终更新的对象EF。它将值从您自己的实体复制到它,这可能会将隐藏的实体标记为
    已修改
显然,通过这个空setter,
CreatedDB
从数据库中获取时总是
null
。对于EF,
CRCreated
不存在。它可能从对象中读取
CreatedDB
值,但空setter再次阻止将其复制到隐藏对象,并将其更新为
null

你必须决定如何解决这个问题。最好的方法可能是让setter实际修改(或创建)CRCreated实例


或者,您可以取消
AddOrUpdate
,自己尝试查找现有对象。如果您找到它,它将不再隐藏,因此您可以随心所欲地使用它。

仔细想想,可能有一个问题,因为CRCreated属性没有存储在数据库中,所以请更新,实体框架在进行比较和运行计算时遇到问题,因为它从数据库获取值,而不是从api获取的对象获取值。我还尝试使用[DatabaseGenerated(DatabaseGenerateOption.Computed)]属性,但这是为了在数据库端进行计算,在创建的对象中没有信息。