EF 4.0 POCO魔法不起作用 - 未检测到任何变化

时间:2010-10-13 14:35:32

标签: entity-framework entity-framework-4 poco

我似乎无法从断开连接的poco对象更新我的数据库。在此示例中,我获取ApplicationUser对象,更新varchar(100)字段SSOID,但没有更改生效。即使我在save方法中重新获取对象,也不会将任何内容发送到db。

如果我尝试调用ApplyCurrentValues,它会抛出

在ObjectStateManager中找不到具有与提供的对象的键匹配的键的对象。验证提供的对象的键值是否与必须应用更改的对象的键值匹配。

 public void Save(ApplicationUser au)
 {
     ApplicationUser original = context.ApplicationUsers.FirstorDefault(a => a.UserID == au.UserID);
     context.ContextOptions.ProxyCreationEnabled = false;  //changing this has no effect

     if(original == null)
     {
         context.AddObject("ApplicationUsers",au); //this works!
     }
     else
     {
          ///let's manually set some properties on the object I just fetched.
          original.SSOID = au.SSOID;
          ObjectStateEntry entry = null;
          context.DetectChanges();
          context.ObjectStateManager.TryGetObjectStateEntry(original.EntityKey, out entry);
          //entry is still null!
          context.ApplicationUsers.ApplyCurrentValues(original);  //BOOM!!
      }
      context.SaveChanges();
      return;
  }

我尝试了我能想到的一切,甚至让ApplicationUser实现System.Data.Objects.DataClasses.IEntityWithKey,这应该是没有必要的。

这是映射:

<EntitySetMapping Name="ApplicationUsers">
    <EntityTypeMapping TypeName="MyCompanyName.ApplicationUser">
         <MappingFragment StoreEntitySet="ApplicationUser">
            <ScalarProperty Name="UserID" ColumnName="UserID" />
            <ScalarProperty Name="SystemID" ColumnName="SystemID" />
            <ScalarProperty Name="Username" ColumnName="Username" />
            <!--snip-->
            <ScalarProperty Name="CreatedOn" ColumnName="CreatedOn" />
            <ScalarProperty Name="CreatedBy" ColumnName="CreatedBy" />
            <ScalarProperty Name="SSOID" ColumnName="SSOID" />
         </MappingFragment>
     </EntityTypeMapping>
</EntitySetMapping>

1 个答案:

答案 0 :(得分:2)

您使用的是简单/简单POCO T4 template,还是自我跟踪实体模板?

直接POCO不支持任何跟踪更改 - 如果您需要,您需要自我跟踪实体。

参见资源:

更新:我认为您非常接近正确的做事方式。您重新加载对象的原始状态(我可能会添加一个时间戳或其他东西的检查,以确保同时没有更改存储中的对象。)

一旦你完成了这项工作,我相信你只需要检测自己发生了哪些变化/ auoriginal之间存在差异;相应地更新original,然后只需致电context.SaveChanges()

据我了解,.DetectChanges()无效,因为您使用直接POCO类而没有任何更改跟踪,例如你的au对象无法知道改变了什么 - 你基本上需要自己进行逐个属性比较。