ef4记录标记,inserted_at,inserted_by

时间:2010-08-24 10:52:47

标签: entity-framework

有没有办法通过所有新的/修改过的实体并设置他们的inserted_at,updated_at字段?

使用ObjectStateManager我可以获得这些实体的列表,但找不到设置实体属性值的方法。

foreach (var item in db.ObjectStateManager.GetObjectStateEntries(EntityState.Added))
{
System.Data.Objects.DataClasses.EntityObject entity = (System.Data.Objects.DataClasses.EntityObject)(item.Entity);
// now how can I set its .inserted_at to DateTime.Now
}

这是我目前的解决方案

public interface IUpdateTrack
{
    DateTime? updated_at { get; set; }
    Guid? updated_by { get; set; }
}
public interface IInsertTrack
{
    DateTime? inserted_at { get; set; }
    Guid? inserted_by { get; set; }
}

在部分类

中实现接口
public partial class crm_customer : BaseDB.IInsertTrack, BaseDB.IUpdateTrack

在存储库类

public void Save()
{
    foreach (var item in db.ObjectStateManager.GetObjectStateEntries(EntityState.Added))
    {
        System.Data.Objects.DataClasses.EntityObject entity = (System.Data.Objects.DataClasses.EntityObject)(item.Entity);
        if (item.Entity is BaseDB.IInsertTrack)
        {
            IInsertTrack insert_track = (IInsertTrack)(item.Entity);
            insert_track.inserted_at = DateTime.Now;
            insert_track.inserted_by = BaseDB.SessionContext.Current.ActiveUser.UserUid;
        }
    }
    foreach (var item in db.ObjectStateManager.GetObjectStateEntries(EntityState.Modified))
    {
        if (item.Entity is BaseDB.IUpdateTrack)
        {
            IUpdateTrack update_track = (IUpdateTrack)(item.Entity);
            update_track.updated_at = DateTime.Now;
            update_track.updated_by = BaseDB.SessionContext.Current.ActiveUser.UserUid;
        }
    }

我想要一个不需要为模型中的每个类实现接口的解决方案,它容易出错,您可能忘记为某些类实现此接口。 我使用数据库优先方法使用EF4。

1 个答案:

答案 0 :(得分:1)

是的,在Entity Framework 4.0中有一个完美的方法,感谢Julia Lerman指出这个好方法。


using System.Data.Common;
using System.Data.Metadata.Edm;
...

var entries = from e in db.ObjectStateManager.GetObjectStateEntries( EntityState.Added | EntityState.Modified) where e.Entity != null select e;

foreach (var entry in entries) {
var fieldMetaData = entry.CurrentValues.DataRecordInfo.FieldMetadata; FieldMetadata updatedAtField = fieldMetaData .Where(f => f.FieldType.Name == "updated_at").FirstOrDefault();

    if (updatedAtField.FieldType != null) {
       string fieldTypeName = updatedAtField.FieldType.TypeUsage.EdmType.Name;

        if (fieldTypeName == PrimitiveTypeKind.DateTime.ToString()) {
            entry.CurrentValues.SetDateTime(updatedAtField.Ordinal, 
                                            DateTime.Now);
        }
    }

}


然后,您可以在SavingChanges事件中调用此代码以确保任何 updated_at字段自动更新。

顺便说一句,System.Data.Metadata.Edm命名空间允许您访问 PrimitiveTypeKind类。