设置更新日期
Set updated date
我先用EF数据库
我有一个 table,其中有一个 'date updated' 列。当记录在其中更新时,它需要具有当前日期时间。我正在使用 EF,所以我无法编辑任何自动生成的模型 classes。我不想编辑 T4 模板,因为我认为如果我升级 EF
它将被覆盖
为了解决一个不同的问题,我遵循了这个:http://www.ozkary.com/2015/01/add-data-annotations-to-entity.html 生成一个 'buddy' class 据我所知只是扩展了自动生成的 EF class
然后我按照这个答案:set default value in class constructor C# 似乎显示了我需要的解决方案。但是当我测试时,DateUpdated
没有改变
这是我自动生成的 class 的一部分。你可以在这里看到DTUpdated
namespace bt2.Models
{
using System;
using System.Collections.Generic;
public partial class Task
{
public int Task_ID { get; set; }
public int TaskType_ID { get; set; }
public int Emp_ID { get; set; }
public System.DateTime DTInserted { get; set; }
public System.DateTime DTUpdated { get; set; }
public virtual TaskType TaskType { get; set; }
public virtual Task Tasks1 { get; set; }
public virtual Task Task1 { get; set; }
}
}
这是我的 'buddy' class,我在其中尝试向自动生成的 class:
添加额外的代码
namespace bt2.Models
{
[MetadataType(typeof(TaskMD))]
public partial class Task
{
}
internal sealed class TaskMD
{
[DisplayName("ID")]
public int Task_ID { get; set; }
[DisplayName("Task Type")]
public int TaskType_ID { get; set; }
public System.DateTime DTUpdated {
get { return DateTime.Now; }
set { this.DTUpdated = value; }
}
}
据我所知,这第二个 class 是对原始 class
的扩展
我想解决我的问题,但我也想在这里更详细地了解发生了什么。
我不完全确定那里发生了什么,但这里有一些建议:
您可以为每个实体和实体中的每个 属性 生成属性。这有点棘手,您甚至可以为实体生成密钥。您可以取消扩展 class 和创建元数据。这反映了您的数据库模式。我在我的项目中使用了这种方法并且有效。
使用 T4 模板自动生成文件是一次性事件(除非您进行了一些更改并且想要 re-generate 所有实体)。因此,建议断开连接并仅使用项目中生成的实体。
因为上下文 class 是部分 class 您可以创建自己的部分 class 并重载 SaveChanges
方法。
在此方法中,您可以使用反射获取 DTUpated
属性 并设置更新日期时间值。 (如果 属性 的名称相同,如果名称不相同,则将名称作为参数传入)
类似下面的内容。
public partial class TBCompanyEntities
{
public void SaveChanges(object o)
{
try
{
var propertyInfo = o.GetType().GetProperty("DTUpdated");
// This hasn't been tested by me yet - will test and update if need changes
if(propertyInfo != null)
propertyInfo.SetValue(o, Convert.ChangeType(DateTime.UtcNow, propertyInfo.PropertyType), null);
}
catch (Exception ex)
{
// Logging.Log.Error(ex);
}
base.SaveChanges();
}
}
然后在你的代码中而不是调用 dbContxt.SaveChanges();
你可以调用
dbContext.SaveChanges(YOUR_ENTITY_OBJECT);
示例:
using (var dbContext = new TBCompanyEntities())
{
// Entity with DTUpdated
var notification = dbContext.NotificationArchives.First(s => s.iNotificationId == 1);
notification.bIsRead = true;
dbContext.SaveChanges(notification);
//Entity without DTUpdated
var asset = dbContext.Assets.First(s => s.iAssetId == 1);
asset.iDriverId = null;
dbContext.SaveChanges();
}
编辑:
覆盖是指被覆盖方法的参数与基本方法相同。
所以你必须这样做:
public partial class TBCompanyEntities
{
public override void SaveChanges()
{
//TODO: Here you will have to detect which entity has been modified/updated.
// This should be possible, by using the Track Entity Changes features
var modifiedEntities = ChangeTracker.Entries()
.Where(p => p.State == EntityState.Modified).ToList();
base.SaveChanges();
}
}
这是一个很好的 link 覆盖,作者在其中跟踪对实体的更改,然后创建一个日志。 (如审计日志)
https://www.exceptionnotfound.net/entity-change-tracking-using-dbcontext-in-entity-framework-6/
我先用EF数据库
我有一个 table,其中有一个 'date updated' 列。当记录在其中更新时,它需要具有当前日期时间。我正在使用 EF,所以我无法编辑任何自动生成的模型 classes。我不想编辑 T4 模板,因为我认为如果我升级 EF
它将被覆盖为了解决一个不同的问题,我遵循了这个:http://www.ozkary.com/2015/01/add-data-annotations-to-entity.html 生成一个 'buddy' class 据我所知只是扩展了自动生成的 EF class
然后我按照这个答案:set default value in class constructor C# 似乎显示了我需要的解决方案。但是当我测试时,DateUpdated
没有改变
这是我自动生成的 class 的一部分。你可以在这里看到DTUpdated
namespace bt2.Models
{
using System;
using System.Collections.Generic;
public partial class Task
{
public int Task_ID { get; set; }
public int TaskType_ID { get; set; }
public int Emp_ID { get; set; }
public System.DateTime DTInserted { get; set; }
public System.DateTime DTUpdated { get; set; }
public virtual TaskType TaskType { get; set; }
public virtual Task Tasks1 { get; set; }
public virtual Task Task1 { get; set; }
}
}
这是我的 'buddy' class,我在其中尝试向自动生成的 class:
添加额外的代码namespace bt2.Models
{
[MetadataType(typeof(TaskMD))]
public partial class Task
{
}
internal sealed class TaskMD
{
[DisplayName("ID")]
public int Task_ID { get; set; }
[DisplayName("Task Type")]
public int TaskType_ID { get; set; }
public System.DateTime DTUpdated {
get { return DateTime.Now; }
set { this.DTUpdated = value; }
}
}
据我所知,这第二个 class 是对原始 class
的扩展我想解决我的问题,但我也想在这里更详细地了解发生了什么。
我不完全确定那里发生了什么,但这里有一些建议:
您可以为每个实体和实体中的每个 属性 生成属性。这有点棘手,您甚至可以为实体生成密钥。您可以取消扩展 class 和创建元数据。这反映了您的数据库模式。我在我的项目中使用了这种方法并且有效。
使用 T4 模板自动生成文件是一次性事件(除非您进行了一些更改并且想要 re-generate 所有实体)。因此,建议断开连接并仅使用项目中生成的实体。
因为上下文 class 是部分 class 您可以创建自己的部分 class 并重载 SaveChanges
方法。
在此方法中,您可以使用反射获取 DTUpated
属性 并设置更新日期时间值。 (如果 属性 的名称相同,如果名称不相同,则将名称作为参数传入)
类似下面的内容。
public partial class TBCompanyEntities
{
public void SaveChanges(object o)
{
try
{
var propertyInfo = o.GetType().GetProperty("DTUpdated");
// This hasn't been tested by me yet - will test and update if need changes
if(propertyInfo != null)
propertyInfo.SetValue(o, Convert.ChangeType(DateTime.UtcNow, propertyInfo.PropertyType), null);
}
catch (Exception ex)
{
// Logging.Log.Error(ex);
}
base.SaveChanges();
}
}
然后在你的代码中而不是调用 dbContxt.SaveChanges();
你可以调用
dbContext.SaveChanges(YOUR_ENTITY_OBJECT);
示例:
using (var dbContext = new TBCompanyEntities())
{
// Entity with DTUpdated
var notification = dbContext.NotificationArchives.First(s => s.iNotificationId == 1);
notification.bIsRead = true;
dbContext.SaveChanges(notification);
//Entity without DTUpdated
var asset = dbContext.Assets.First(s => s.iAssetId == 1);
asset.iDriverId = null;
dbContext.SaveChanges();
}
编辑:
覆盖是指被覆盖方法的参数与基本方法相同。
所以你必须这样做:
public partial class TBCompanyEntities
{
public override void SaveChanges()
{
//TODO: Here you will have to detect which entity has been modified/updated.
// This should be possible, by using the Track Entity Changes features
var modifiedEntities = ChangeTracker.Entries()
.Where(p => p.State == EntityState.Modified).ToList();
base.SaveChanges();
}
}
这是一个很好的 link 覆盖,作者在其中跟踪对实体的更改,然后创建一个日志。 (如审计日志)
https://www.exceptionnotfound.net/entity-change-tracking-using-dbcontext-in-entity-framework-6/