我首先使用EF数据库
我的表中有一个“更新日期”列。当记录更新时,它需要具有当前日期时间。我正在使用EF,所以我无法编辑任何自动生成的模型类。我不想编辑T4模板,因为我认为如果我升级EF
将被覆盖为了解决另一个问题,我遵循了这个:http://www.ozkary.com/2015/01/add-data-annotations-to-entity.html来生成一个'伙伴'类,据我所知,只是扩展自动生成的EF类
然后我按照这个答案:set default value in class constructor C#这似乎显示了我需要的解决方案。但是,当我测试时,DateUpdated
未更改
这是我自动生成课程的一部分。您可以在此处看到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'类,我试图在自动生成的类中添加额外的代码:
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; }
}
}
据我所知,第二课正在扩展原来的课程
我想解决我的问题,但我也想了解这里有更详细的内容。
答案 0 :(得分:0)
我不完全确定那里发生了什么,但这里有一些建议:
您可以为实体中的每个实体和每个属性生成属性。这有点棘手,您甚至可以为实体生成密钥。您可以消除扩展该类并创建元数据。这反映了您的数据库架构。我在我的项目中使用了这种方法并且有效。
使用T4模板自动生成的文件是一次性事件(除非您有一些更改,并且您想要重新生成所有实体)。因此,建议将其断开连接并仅使用项目中生成的实体。
答案 1 :(得分:0)
因为Context类是Partial类,所以您可以使用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();
}
}
这是一个很好的覆盖链接,其中作者跟踪对实体的更改,然后创建一个Log。 (如审核日志)
https://www.exceptionnotfound.net/entity-change-tracking-using-dbcontext-in-entity-framework-6/