EF 4.0 POCO magic не работает - Изменения не обнаружены - PullRequest
3 голосов
/ 13 октября 2010

Я не могу обновить свою базу данных из отключенных объектов Poco.В этом примере я выбираю объект ApplicationUser, обновляю поле SSOID поля varchar (100), но изменения не вступают в силу.Даже когда я повторно получаю объект в методе сохранения, в базу данных ничего не отправляется.

Если я пытаюсь вызвать 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 Ответ

2 голосов
/ 13 октября 2010

Используете ли вы простой / простой шаблон POCO T4 или шаблон самопровозглашенных объектов ??

Прямой POCO не поддерживает отслеживание каких-либо изменений - если вы этого хотите, вам нужны объекты самообследования.

См. Ресурсы:

Обновление: Я думаю, что вы достаточно близки к правильному способу ведения дел здесь. Вы перезагружаете исходное состояние объекта (я бы, вероятно, добавил проверку временной метки или чего-то еще, чтобы убедиться, что объект в хранилище не изменился за это время).

Как только вы это сделаете, я считаю, что вам просто нужно выяснить, какие изменения произошли / где существуют различия между au и original; обновите original соответственно, а затем просто позвоните context.SaveChanges().

Насколько я понимаю, .DetectChanges() не может работать, поскольку вы используете прямые классы POCO без какого-либо отслеживания изменений, например, у вашего au объекта нет никакого способа узнать, что было изменено - вам, в основном, нужно сделать сравнение свойство за свойством самостоятельно.

...