2010-09-06 2 views
2

У меня есть объект Project в моей сущности. Я создаю проект по:Сохранение отредактированного объекта в Entity Framework

public static void Add(Project project) 
     { 
      var context = new Entities(); 
      context.AddToProjects(project); 

      context.SaveChanges(); 
     } 

Далее я получаю этот объект:

public static Project GetProjectById(int idProject) 
     { 
      var context = new Entities(); 
      return context.Projects.Where(p => p.IDProject == idProject).First(); 
     } 

И эти два метода прекрасно работают.

Но, когда я хочу, чтобы сохранить отредактированный задачу:

public static void SaveProject(Project project) 
     { 
      var context = new Entities(); 
      project.EntityKey = new EntityKey("Entities.Projects", "IDProject", project.IDProject); 
      context.Attach(project); 
      context.SaveChanges(); 
     } 

метод exectues без каких-либо исключений. Но в базе данных ничего не меняется. Что я должен изменить?

Это мой enity:

[EdmEntityTypeAttribute(NamespaceName="GWDModel", Name="Project")] 
    [Serializable()] 
    [DataContractAttribute(IsReference=true)] 
    public partial class Project : EntityObject 
    { 
     #region Factory Method 

    /// <summary> 
    /// Create a new Project object. 
    /// </summary> 
    /// <param name="iDProject">Initial value of the IDProject property.</param> 
    /// <param name="name">Initial value of the Name property.</param> 
    /// <param name="expectedCost">Initial value of the ExpectedCost property.</param> 
    /// <param name="status">Initial value of the Status property.</param> 
    public static Project CreateProject(global::System.Int32 iDProject, global::System.String name, global::System.Decimal expectedCost, StatusOfProjectWrapper status) 
    { 
     Project project = new Project(); 
     project.IDProject = iDProject; 
     project.Name = name; 
     project.ExpectedCost = expectedCost; 
     project.Status = StructuralObject.VerifyComplexObjectIsNotNull(status, "Status"); 
     return project; 
    } 

    #endregion 
    #region Primitive Properties 

    /// <summary> 
    /// No Metadata Documentation available. 
    /// </summary> 
    [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] 
    [DataMemberAttribute()] 
    public global::System.Int32 IDProject 
    { 
     get 
     { 
      return _IDProject; 
     } 
     set 
     { 
      if (_IDProject != value) 
      { 
       OnIDProjectChanging(value); 
       ReportPropertyChanging("IDProject"); 
       _IDProject = StructuralObject.SetValidValue(value); 
       ReportPropertyChanged("IDProject"); 
       OnIDProjectChanged(); 
      } 
     } 
    } 
    private global::System.Int32 _IDProject; 
    partial void OnIDProjectChanging(global::System.Int32 value); 
    partial void OnIDProjectChanged(); 

    /// <summary> 
    /// No Metadata Documentation available. 
    /// </summary> 
    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] 
    [DataMemberAttribute()] 
    public global::System.String Name 
    { 
     get 
     { 
      return _Name; 
     } 
     set 
     { 
      OnNameChanging(value); 
      ReportPropertyChanging("Name"); 
      _Name = StructuralObject.SetValidValue(value, false); 
      ReportPropertyChanged("Name"); 
      OnNameChanged(); 
     } 
    } 
    private global::System.String _Name; 
    partial void OnNameChanging(global::System.String value); 
    partial void OnNameChanged(); 

    /// <summary> 
    /// No Metadata Documentation available. 
    /// </summary> 
    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] 
    [DataMemberAttribute()] 
    public global::System.Decimal ExpectedCost 
    { 
     get 
     { 
      return _ExpectedCost; 
     } 
     set 
     { 
      OnExpectedCostChanging(value); 
      ReportPropertyChanging("ExpectedCost"); 
      _ExpectedCost = StructuralObject.SetValidValue(value); 
      ReportPropertyChanged("ExpectedCost"); 
      OnExpectedCostChanged(); 
     } 
    } 
    private global::System.Decimal _ExpectedCost; 
    partial void OnExpectedCostChanging(global::System.Decimal value); 
    partial void OnExpectedCostChanged(); 

    /// <summary> 
    /// No Metadata Documentation available. 
    /// </summary> 
    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] 
    [DataMemberAttribute()] 
    public Nullable<global::System.DateTime> PlannedStart 
    { 
     get 
     { 
      return _PlannedStart; 
     } 
     set 
     { 
      OnPlannedStartChanging(value); 
      ReportPropertyChanging("PlannedStart"); 
      _PlannedStart = StructuralObject.SetValidValue(value); 
      ReportPropertyChanged("PlannedStart"); 
      OnPlannedStartChanged(); 
     } 
    } 
    private Nullable<global::System.DateTime> _PlannedStart; 
    partial void OnPlannedStartChanging(Nullable<global::System.DateTime> value); 
    partial void OnPlannedStartChanged(); 

    /// <summary> 
    /// No Metadata Documentation available. 
    /// </summary> 
    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] 
    [DataMemberAttribute()] 
    public Nullable<global::System.DateTime> PlannedEnd 
    { 
     get 
     { 
      return _PlannedEnd; 
     } 
     set 
     { 
      OnPlannedEndChanging(value); 
      ReportPropertyChanging("PlannedEnd"); 
      _PlannedEnd = StructuralObject.SetValidValue(value); 
      ReportPropertyChanged("PlannedEnd"); 
      OnPlannedEndChanged(); 
     } 
    } 
    private Nullable<global::System.DateTime> _PlannedEnd; 
    partial void OnPlannedEndChanging(Nullable<global::System.DateTime> value); 
    partial void OnPlannedEndChanged(); 

    /// <summary> 
    /// No Metadata Documentation available. 
    /// </summary> 
    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] 
    [DataMemberAttribute()] 
    public Nullable<global::System.DateTime> DateOfStart 
    { 
     get 
     { 
      return _DateOfStart; 
     } 
     set 
     { 
      OnDateOfStartChanging(value); 
      ReportPropertyChanging("DateOfStart"); 
      _DateOfStart = StructuralObject.SetValidValue(value); 
      ReportPropertyChanged("DateOfStart"); 
      OnDateOfStartChanged(); 
     } 
    } 
    private Nullable<global::System.DateTime> _DateOfStart; 
    partial void OnDateOfStartChanging(Nullable<global::System.DateTime> value); 
    partial void OnDateOfStartChanged(); 

    /// <summary> 
    /// No Metadata Documentation available. 
    /// </summary> 
    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] 
    [DataMemberAttribute()] 
    public Nullable<global::System.DateTime> DateOfEnd 
    { 
     get 
     { 
      return _DateOfEnd; 
     } 
     set 
     { 
      OnDateOfEndChanging(value); 
      ReportPropertyChanging("DateOfEnd"); 
      _DateOfEnd = StructuralObject.SetValidValue(value); 
      ReportPropertyChanged("DateOfEnd"); 
      OnDateOfEndChanged(); 
     } 
    } 
    private Nullable<global::System.DateTime> _DateOfEnd; 
    partial void OnDateOfEndChanging(Nullable<global::System.DateTime> value); 
    partial void OnDateOfEndChanged(); 

    /// <summary> 
    /// No Metadata Documentation available. 
    /// </summary> 
    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] 
    [DataMemberAttribute()] 
    public Nullable<global::System.Decimal> CurrentCost 
    { 
     get 
     { 
      return _CurrentCost; 
     } 
     set 
     { 
      OnCurrentCostChanging(value); 
      ReportPropertyChanging("CurrentCost"); 
      _CurrentCost = StructuralObject.SetValidValue(value); 
      ReportPropertyChanged("CurrentCost"); 
      OnCurrentCostChanged(); 
     } 
    } 
    private Nullable<global::System.Decimal> _CurrentCost; 
    partial void OnCurrentCostChanging(Nullable<global::System.Decimal> value); 
    partial void OnCurrentCostChanged(); 

    #endregion 
    #region Complex Properties 

    /// <summary> 
    /// No Metadata Documentation available. 
    /// </summary> 
    [EdmComplexPropertyAttribute()] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
    [XmlElement(IsNullable=true)] 
    [SoapElement(IsNullable=true)] 
    [DataMemberAttribute()] 
    public StatusOfProjectWrapper Status 
    { 
     get 
     { 
      _Status = GetValidValue(_Status, "Status", false, _StatusInitialized); 
      _StatusInitialized = true; 
      return _Status; 
     } 
     set 
     { 
      OnStatusChanging(value); 
      ReportPropertyChanging("Status"); 
      _Status = SetValidValue(_Status, value, "Status"); 
      _StatusInitialized = true; 
      ReportPropertyChanged("Status"); 
      OnStatusChanged(); 
     } 
    } 
    private StatusOfProjectWrapper _Status; 
    private bool _StatusInitialized; 
    partial void OnStatusChanging(StatusOfProjectWrapper value); 
    partial void OnStatusChanged(); 

    #endregion 

    #region Navigation Properties 

    /// <summary> 
    /// No Metadata Documentation available. 
    /// </summary> 
    [XmlIgnoreAttribute()] 
    [SoapIgnoreAttribute()] 
    [DataMemberAttribute()] 
    [EdmRelationshipNavigationPropertyAttribute("GWDModel", "FK_ProjectChanges_Projects", "ProjectChanges")] 
    public EntityCollection<ProjectChanx> ProjectChanges 
    { 
     get 
     { 
      return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<ProjectChanx>("GWDModel.FK_ProjectChanges_Projects", "ProjectChanges"); 
     } 
     set 
     { 
      if ((value != null)) 
      { 
       ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<ProjectChanx>("GWDModel.FK_ProjectChanges_Projects", "ProjectChanges", value); 
      } 
     } 
    } 

    /// <summary> 
    /// No Metadata Documentation available. 
    /// </summary> 
    [XmlIgnoreAttribute()] 
    [SoapIgnoreAttribute()] 
    [DataMemberAttribute()] 
    [EdmRelationshipNavigationPropertyAttribute("GWDModel", "ProjectManagers", "Users")] 
    public EntityCollection<User> Users 
    { 
     get 
     { 
      return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<User>("GWDModel.ProjectManagers", "Users"); 
     } 
     set 
     { 
      if ((value != null)) 
      { 
       ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<User>("GWDModel.ProjectManagers", "Users", value); 
      } 
     } 
    } 

    /// <summary> 
    /// No Metadata Documentation available. 
    /// </summary> 
    [XmlIgnoreAttribute()] 
    [SoapIgnoreAttribute()] 
    [DataMemberAttribute()] 
    [EdmRelationshipNavigationPropertyAttribute("GWDModel", "FK_Milestones_Projects", "Milestone")] 
    public EntityCollection<Milestone> Milestones 
    { 
     get 
     { 
      return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Milestone>("GWDModel.FK_Milestones_Projects", "Milestone"); 
     } 
     set 
     { 
      if ((value != null)) 
      { 
       ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Milestone>("GWDModel.FK_Milestones_Projects", "Milestone", value); 
      } 
     } 
    } 

    #endregion 
} 

ответ

1

У вас есть два варианта. Первый выбор заключается в совместном использовании контекста между GetProjectById и SaveProject. Чем ваше лицо будет отслеживать изменения, и вам не нужно будет называть Attach. Если вам нужно/нужно открыть новый контекст для каждой операции, вы должны указать, что проект был изменен. Когда объект привязан к контексту, он отслеживается как неизменный. Вы должны вручную изменить состояние объекта, чтобы изменить его, вызвав ObjectStateManager после присоединения:

context.ObjectStateManager.ChangeObjectState(project, EntityState.Modified); 

Btw. ObjectContext является одноразовым, поэтому вы должны его обработать, используя или попробуйте/наконец.

Edit:

Основываясь на ваш комментарий о WCF первого выбора не представляется возможным. Но вы также можете проверить объекты Self Tracking (только EF 4.0).

+0

FYI , Метод ChangeObjectState доступен только с EF 4.0. @phenevo, ChangeObjectState - довольно удобный метод, но обратите внимание, что он отмечает все свойства как измененные - может быть проблемой, если вы занимаетесь оптимальной обработкой параллелизма. – VinayC

1

Это зависит от того, как ваш извлечения проекта для редактирования. Если вы получите его в соответствии с вашим методом GetProjectById, то этот объект проекта имеет свои изменения, отслеживаемые соответствующим объектом ObjectContext.

От MSDN:

Платформа Entity Framework отслеживает изменения объектов, которые прикреплены к ObjectContext. Инструменты модели данных сущности генерируют пару частичных методов с именем OnPropertyChanging и OnPropertyChanged. Эти методы вызывают в настройщике свойств.

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

Я бы рекомендовал использовать шаблон репозитория для управления объектами ObjectContext, чтобы у вас было правильное отслеживание ObjectContext и сохранение изменений.

+0

Я перевел эти объекты на datacontract (WCF), и когда datacontract поддерживает, я перевешу его в новый экземпляр Project с теми же свойствами, поэтому отслеживание не работает в этой ситуации, спасибо вам за ответ :) – user278618

3

EF Контекст отслеживает изменения сущностей - поэтому, если вы отсоединяете/присоединяете объекты, изменения не отслеживаются. Теперь, когда вы пытаетесь обновить объект обратно, привязавшись к контексту, из контекстной перспективы, объект не имеет никаких изменений. Поэтому SaveChanges не пытается ничего сохранить. Вы должны как-то пометить свой объект как грязный или измененный, прежде чем вызвать метод SaveChanges. Для достижения этой цели см. this blog post. И вот yet another post, изложив аналогичное решение.

Смежные вопросы