DbContext实体框架Datetime.Now字段 [英] DbContext Entity framework Datetime.Now fields

查看:221
本文介绍了DbContext实体框架Datetime.Now字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有两个数据类型为datetime的字段。


  • 添加

  • 修改



当为两个字段插入新的记录值时,必须为 System.DateTime.Now;
,但只在更新修改需要更改。



我可以将 StoreGeneratedPattern 设置为计算的并处理修改字段与数据库中的 GETDATE(),但问题是字段添加



我的猜测是我必须覆盖 SavingChanges() code>或类似的东西,但不知道如何。



编辑:我到目前为止尝试过




  • 在我的项目中添加另一个类,使用fallowing代码

     命名空间Winpro 
    {
    public partial class Customer
    {
    public Customer()
    {
    this.Added = DateTime.UtcNow;
    }
    }
    }

    但是无法构建解决方案



    键入'Winpro.Customer'已经使用相同的参数类型定义了名为Customer的成员



解决方案

过去我们做了类似的事情。



需要存储Date和Time并负责创建记录。另外,在每一个变化中,如果有一个审计记录,基准记录也应该得到一个日期和时间,用户负责更改。



这是什么我们已经完成了:



界面



为了增加一些标准行为,使事情更具可扩展性,我们创建了两个界面如下:

  public interface IAuditCreated 
{
DateTime CreatedDateTime {get;组; }
string CreationUser {get;组;
}

public interface IAuditChanged
{
DateTime LastChangeDateTime {get;组; }
string LastChangeUser {get;组;
}



覆盖SaveChanges()以添加一些自动控制



  public class WhateverContext:DbContext 
{
//某些行为和所有...

public覆盖int SaveChanges()
{
//添加...
var _entitiesAdded = ChangeTracker.Entries()
.Where(_e => _e.State == EntityState 。添加)
.Where(_e => _e.Entity.GetType()。GetInterfaces()。Any(_i => _i == typeof(IAuditCreated)))
.Select(_e = > _e.Entity);
foreach(var _entity in _entitiesAdded){/ *设置日期和用户* /}

//更改...
var _entitiesChanged = ChangeTracker.Entries()
.Where(_e => _e.State == EntityState.Modified)
.Where(_e => _e.Entity.GetType()。GetInterfaces()。Any(_i => _i == typeof(IAuditChanged)))
.Select(_e => _e.Entity);
foreach(__entitiesChanged中的var _entity){/ *设置日期和用户* /}

//保存...
return base.SaveChanges();
}
}



不要简单地复制粘贴!



这段代码是在几年前写的,在EntityFramework v4的时代。它假设您已经检测到更改(ChangeTracker可用)和其他一些。



此外,我们绝对不知道这些代码是如何影响性能的。这是因为这个系统的使用与更新相比是非常或与查看相关的,也是因为它是一个桌面应用程序,所以我们有足够的可用内存和处理时间浪费。



你应该考虑到这一点,你可能会找到一个更好的方式来实现这一点。但是整个想法是一样的:过滤哪些实体正在更新,哪些实体正在被正确处理。



另一种方法



有很多方法。另一个可能在某些情况下(或更复杂)的性能更好是具有类似于EF代理的某种代理,处理它。



再次,即使有一个空的界面,有一个可以清楚区分可审计记录和常规记录。



如果可能强制所有他们具有相同的属性名称和类型,请执行此操作。


Have two fields with data type datetime.

  • Added
  • Modified

When inserting new record values for both fields must be System.DateTime.Now; but when updating only Modified needs to be changed.

I can set StoreGeneratedPattern to Computed and handle Modified field with GETDATE() in database but problem is field Added.

My guess is that I have to override SavingChanges() or something similar but don't know how.

EDIT : What I have try so far

  • Added another class in my project with fallowing code

    namespace Winpro
    {
        public partial class Customer
        {
            public Customer()
            {
                this.Added = DateTime.UtcNow;
            }
        }
    }
    

    but then cannot build solution

    Type 'Winpro.Customer' already defines a member called 'Customer' with the same parameter types

解决方案

We did something quite similar in the past.

There was the need to store both Date and Time and the responsible for creating the record. Also, on every change, dispite if there's an audit record or not, the base record should also get a Date and Time and the user responsible for the changes.

Here's what we have done:

Interfaces

To add some standard behavior and make things more extensible, we've created two interfaces, as follows:

public interface IAuditCreated
{
   DateTime CreatedDateTime { get; set; }
   string CreationUser { get; set; }
}

public interface IAuditChanged
{
   DateTime LastChangeDateTime { get; set; }
   string LastChangeUser { get; set; }
}

Override SaveChanges() to add some automatic control

public class WhateverContext : DbContext
{
   // Some behavior and all...

   public override int SaveChanges()
   {
      // Added ones...
      var _entitiesAdded = ChangeTracker.Entries()
         .Where(_e => _e.State == EntityState.Added)
         .Where(_e => _e.Entity.GetType().GetInterfaces().Any(_i => _i == typeof(IAuditCreated)))
         .Select(_e => _e.Entity);
      foreach(var _entity in _entitiesAdded) { /* Set date and user */ }

      // Changed ones...
      var _entitiesChanged = ChangeTracker.Entries()
         .Where(_e => _e.State == EntityState.Modified)
         .Where(_e => _e.Entity.GetType().GetInterfaces().Any(_i => _i == typeof(IAuditChanged)))
         .Select(_e => _e.Entity);
      foreach(var _entity in _entitiesChanged) { /* Set date and user */ }

      // Save...
      return base.SaveChanges();
   }
}

Do not simply copy and paste!

This code was written a few years ago, on the age of EntityFramework v4. It assumes that you have already detected changes (ChangeTracker available) and some other.

Also, we have absolutely no idea of how this code impacts performance on any way. That's because the usage of this system is much or related to viewing than updating and also because it's a desktop application, so we have plenty available memory and processing time to waste.

You should take that into account and you might find a better way to implement this. But the whole idea is the same: filter which entities are being updated and which are being added to properly handle that.

Another approach

There are many approaches to this. One other that might be better for performance on some cases (but also more complex) is to have some sort of proxy, similar to an EF proxy, handling that.

Again, even with an empty interface, it's good to have one to clearly distinguish between auditable records and regular ones.

If possible to force all of them having the same property name and type, do it.

这篇关于DbContext实体框架Datetime.Now字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆