是否可以在ObjectStateManagerChanged处理程序中修改实体对象?

本文关键字:修改 实体 对象 程序 处理 ObjectStateManagerChanged 是否 | 更新日期: 2023-09-27 18:06:22

下面是我需要实现的业务逻辑:

数据模型中有多种实体类型,例如:User, UserProfile, UserProfileValue, UserExtendedData等

当创建像User这样的实体时,我需要自动创建其他逻辑链接的实体(通常在db中具有1:1的关系),例如UserProfile。

每个实体都有一个具有OnCreating/OnCreated, OnUpdating/OnUpdated方法的控制器,这些方法是从我的datcontext类的重写SaveChanges方法中调用的。

public override int SaveChanges(SaveOptions options)
{
    IEnumerable<ObjectStateEntry> addedEntities = ObjectStateManager.GetObjectStateEntries(EntityState.Added);
    IEnumerable<ObjectStateEntry> changedEntities = ObjectStateManager.GetObjectStateEntries(EntityState.Modified);
    IEnumerable<ObjectStateEntry> deletedEntities = ObjectStateManager.GetObjectStateEntries(EntityState.Deleted);
    InvokeSavingControllers(addedEntities, changedEntities, deletedEntities);
    //some other code
    int rowsAffected = base.SaveChanges(options);
    InvokeSavedControllers(addedEntities, changedEntities, deletedEntities);
    return rowsAffected;
}

如果我在User.OnCreating()方法中实现了自动创建,那么最终不会为所有自动创建的子实体调用OnCreating()控制器,因为集合addedEntities没有更新新条目。

我的一个想法是通过处理数据上下文的ObjectStateManagerChanged来执行依赖实体的自动创建

private void ObjectStateManagerObjectStateManagerChanged(object sender, System.ComponentModel.CollectionChangeEventArgs e)
{
    if (e.Action == CollectionChangeAction.Add)
    {
        var state = ObjectStateManager.GetObjectStateEntry(e.Element).State;
        if (state == EntityState.Added)
        {
            //should call on creating handlers
            if (e.Element is User)
            {
                User user = (User)e.Element;
                user.UserProfile = UserProfile.CreateDefaultProfile();
            }
        }
    }
}

但不幸的是,我得到nullreference异常,如果我这样做。即使我试图修改ObjectStateManagerObjectStateManagerChanged中的用户属性,我也会得到异常。

对于如何实现所需的功能有什么想法或建议吗?

编辑:

Null Reference:

System.NullReferenceException was unhandled by user code
  Message=Object reference not set to an instance of an object.
  Source=System.Data.Entity
  StackTrace:
       at System.Data.Objects.ObjectContext.AddSingleObject(EntitySet entitySet, IEntityWrapper wrappedEntity, String argumentName)
       at System.Data.Objects.ObjectContext.AddObject(String entitySetName, Object entity)
       at Edm.Entity.Entities.AddObject(Object entity) 

Edm.Entity.Entities.AddObject(Object entity)是新的User对象添加到上下文中。

EDIT2: 不知道我改变了什么,但是上面的代码开始抛出以下异常:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  <code></code>
  <message xml:lang="en-US">An error occurred while processing this request.</message>
  <innererror>
    <message>Object reference not set to an instance of an object.</message>
    <type>System.NullReferenceException</type>
    <stacktrace>   at System.Data.Objects.DataClasses.EntityReference`1.Exclude()&#xD;
   at System.Data.Objects.DataClasses.RelationshipManager.RemoveRelatedEntitiesFromObjectStateManager(IEntityWrapper wrappedEntity)&#xD;
   at System.Data.Objects.ObjectContext.AddObject(String entitySetName, Object entity)&#xD;
   at System.Data.Services.Providers.ObjectContextServiceProvider.CreateResource(String containerName, String fullTypeName)&#xD;
   at System.Data.Services.UpdatableWrapper.CreateResource(String containerName, String fullTypeName)&#xD;
   at System.Data.Services.Serializers.SyndicationDeserializer.CreateObject(SegmentInfo segmentInfo, Boolean topLevel, SyndicationItem item)&#xD;
   at System.Data.Services.Serializers.SyndicationDeserializer.CreateSingleObject(SegmentInfo segmentInfo)&#xD;
   at System.Data.Services.Serializers.Deserializer.ReadEntity(RequestDescription requestDescription)&#xD;
   at System.Data.Services.Serializers.Deserializer.HandlePostRequest(RequestDescription requestDescription)&#xD;
   at System.Data.Services.DataService`1.HandlePostOperation(RequestDescription description, IDataService dataService)&#xD;
   at System.Data.Services.DataService`1.ProcessIncomingRequest(RequestDescription description, IDataService dataService)&#xD;
   at System.Data.Services.DataService`1.BatchDataService.HandleBatchContent(Stream responseStream)</stacktrace>
  </innererror>
</error>

是否可以在ObjectStateManagerChanged处理程序中修改实体对象?

我也有同样的问题。在ObjectStateManagerChanged事件期间添加另一个EntityObject似乎是一个问题。奇怪的是,我的代码(你的代码可能也是)在。net 3.5中工作得很好,但在4.0中给出了一个NullReferenceException。

我调试了。net框架,发现它在内部ObjectContext中崩溃了。在调用ObjectStateManagerChanged事件后调用AddSingleObject方法。发生此异常是因为内部processsedentities哈希集在公共AddObject方法结束时被设为空。但是,如果EntityObject是在ObjectStateManagerChanged事件期间创建的,则该哈希集不应该为空。

这似乎是一个。net framework 4.0的错误