c# - Entity Framework 服务器端计算值

标签 c# asp.net .net entity-framework entity-framework-6

我正在使用一个具有以下时间类的 api。

public class CRTime
{
    public DateTime? datetime { get; set; }
    public string timezone { get; set; }
}

我想将其转换为单个日期时间字段。

下面是返回给我的完整对象的示例,以及我如何尝试计算随后将存储在数据库中的 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 对象中,然后将其传递给 Entity Framework AddOrUpdate。

最佳答案

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

显然,

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

  • 在数据库中找不到该实体;您的实体对象被标记为已添加
  • 它确实找到了一个实体,但与您的预期相反,您的实体对象仍然分离!找到的实体仍然隐藏,这就是 EF 最终更新的对象。它将值从您自己的实体复制到其中,这可能会将隐藏实体标记为已修改

显然,通过这个空 setter ,从数据库获取CreatedDB 时,它始终为null。对于 EF,CRCreated 不存在。它可能从您的对象中读取一个 CreatedDB 值,但空的 setter 再次阻止它被复制到隐藏对象,并且它被更新为 null

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

或者,您可以取消 AddOrUpdate 并尝试自己查找现有对象。如果你找到了它,它就不再隐藏了,所以你可以用它做任何你喜欢的事情。

关于c# - Entity Framework 服务器端计算值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37643563/

相关文章:

c# - 在 getAsync 中为客户端添加 header (在 using block 中)

javascript - 代码可以在 CSHTML 中运行,但不能在外部 Javascript 文件中运行

c# - 表单的关键事件丢失

c# - WinForms 中的用户输入验证

c# - Fluent Nhibernate 映射问题

c# - 在 chrome 中滚动 ListBox 时回发

c# - 从 ASP.NET 应用程序获取入口程序集

c# - 如何操作字符串并从 asp.net c# 中的列表框绑定(bind)中删除 '\'

C# 控制台 - 将光标位置设置为最后一个可见行

c# - 在 C# 中序列化数组