2011-04-26 99 views
2

我想向我的实体添加一些自定义逻辑。每个实体都有一个CreatedBy & LastUpdatedBy属性。实体框架4自定义逻辑保存更改

我已经添加了下面的代码工作正常,如果我添加例如一个人和他们的地址在旅途中。

但是,如果我添加Person并调用context.SaveChanges(),然后添加他们的地址并调用context.SaveChanges()。该代码执行但“entry”的值为空,因此CreatedBy & LastUpdatedBy未填充。

CustomRepository.CurrentUser只是获取用户名。

ObjectSet = context.CreateObjectSet<TEntity>(); 

BusinessEntities.Person person = new BusinessEntities.Person() 
{ 
    TitleRef = 123, 
    FirstName = "FirstName", 
    Surname = "Surname", 
    PhoneNumber = "PhoneNumber", 
    MobileNumber = "MobileNumber", 
    EmailAddress = "EmailAddress", 
}; 


ObjectSet.AddObject(entity); 

Context.SaveChanges(); 

PersonAddress personAddress = new BusinessEntities.PersonAddress 
{ 
    StartDate = DateTime.Now, 
    EndDate = DateTime.Now, 
    OtherResidents = "OtherResidents", 
    CurrentAddress = true, 
    Address = new Address 
    { 
     Address1 = "Address1", 
     Address2 = "Address2", 
     Address3 = "Address3" 
    } 
}; 

Context.SaveChanges(); 


public override int SaveChanges(SaveOptions options) 
{ 
    foreach (ObjectStateEntry entry in 
     ObjectStateManager.GetObjectStateEntries(
     EntityState.Added | EntityState.Modified)) 
    { 
     System.Collections.ObjectModel.ReadOnlyCollection<FieldMetadata> fieldsMetaData = entry.CurrentValues 
           .DataRecordInfo.FieldMetadata; 

     FieldMetadata createdField = fieldsMetaData 
     .Where(f => f.FieldType.Name == "CreatedBy").FirstOrDefault(); 

     FieldMetadata modifiedField = fieldsMetaData 
     .Where(f => f.FieldType.Name == "LastUpdatedBy").FirstOrDefault(); 

     if (modifiedField.FieldType != null) 
     { 
      string fieldTypeName = modifiedField.FieldType.TypeUsage.EdmType.Name; 
      if (fieldTypeName == PrimitiveTypeKind.String.ToString()) 
      { 
       if (entry.CurrentValues[createdField.Ordinal].ToString() == null || 
        entry.CurrentValues[createdField.Ordinal].ToString() == String.Empty) 
       { 
        entry.CurrentValues.SetString(createdField.Ordinal, CustomRepository.CurrentUser); 
       } 

       entry.CurrentValues.SetString(modifiedField.Ordinal, CustomRepository.CurrentUser); 
      } 
     } 
    } 
    return base.SaveChanges(options); 
} 

------------------------原始方法----------------- ------------

private void Initialize() 
{ 
    // Creating proxies requires the use of the ProxyDataContractResolver and 
    // may allow lazy loading which can expand the loaded graph during serialization. 
    ContextOptions.ProxyCreationEnabled = false; 
    ObjectMaterialized += new ObjectMaterializedEventHandler(HandleObjectMaterialized); 

    OnContextCreated(); 
} 

private void OnContextCreated() 
{  
    this.SavingChanges += Context_SavingChanges; 
} 

private void Context_SavingChanges(object sender, EventArgs e) 
{ 
    try 
    { 
     IEnumerable<ObjectStateEntry> objectStateEntries = 
     from ose 
     in this.ObjectStateManager.GetObjectStateEntries(EntityState.Added 
                  | EntityState.Modified) 
     where ose.Entity != null 
     select ose; 

     foreach (ObjectStateEntry entry in objectStateEntries) 
     { 
      System.Collections.ObjectModel.ReadOnlyCollection<FieldMetadata> fieldsMetaData = entry.CurrentValues 
       .DataRecordInfo.FieldMetadata; 

      FieldMetadata createdField = fieldsMetaData 
      .Where(f => f.FieldType.Name == "CreatedBy").FirstOrDefault(); 

      FieldMetadata modifiedField = fieldsMetaData 
      .Where(f => f.FieldType.Name == "LastUpdatedBy").FirstOrDefault(); 

      if (modifiedField.FieldType != null) 
      { 
       string fieldTypeName = modifiedField.FieldType.TypeUsage.EdmType.Name; 
       if (fieldTypeName == PrimitiveTypeKind.String.ToString()) 
       { 
        if (entry.CurrentValues[createdField.Ordinal].ToString() == null || 
         entry.CurrentValues[createdField.Ordinal].ToString() == String.Empty) 
        { 
         entry.CurrentValues.SetString(createdField.Ordinal, CustomRepository.CurrentUser); 
        } 

        entry.CurrentValues.SetString(modifiedField.Ordinal, CustomRepository.CurrentUser); 
       } 
      } 
     } 
    } 
} 
+1

您还应该显示您的“人员”和“地址”实体,以及如何添加它们。 – 2011-04-26 17:51:17

回答

0

您应该处理SavingChanges事件,而不是覆盖该方法。

此外,为什么不让你的实体从基类继承或实现一个接口,而不是使用反射?如果您首先使用模型/数据库,您可以在T4模板中执行此操作,或者如果您先使用代码,则可以直接在T4模板中执行此操作,从长远来看,您可以获得比反射更好的结果。您也可以编写通用筛选器来查找在日期范围内修改的实体,因为您可以针对您的界面进行工作。

我使用ObjectStateManager.GetObjectStateEntries(EntityState.Modified).OfType(Of T)(或任何我想要的状态,无论我想要哪种实体类型) - 它使我可以针对实际实体而不是ObjectStateEntry工作。

+0

我使用T4与POCO Self Tracking并将我的代码分离到不同的项目中。我创建了一个实现通用功能的BaseRepository类。我已经实现了this.SavingChanges + = Context_SavingChanges;并使用ObjectStateManager,但同样存在问题。刚刚在上面编辑。 – markpcasey 2011-04-27 10:32:44

+0

嗨,我仍然坚持在这个问题任何帮助woyuld是伟大的。我的实体像这样继承Person:IObjectWithChangeTracker,INotifyPropertyChanged使用T4 temlpates。 – markpcasey 2011-05-05 12:34:53

2

我终于得到了答案。我需要在Save()之前调用Context.DetectChanges(),否则不会检测到更改。