简体   繁体   中英

Saving edited object in Entity Framework

I have object Project in my entity. I create project by:

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

            context.SaveChanges();
        }

Next I get this object:

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

And this two methods work fine.

But, when I want to save edited task by:

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

method exectues with no exceptions. But in database nothing changes. What I must to change ?

This is my 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
}

EF Context tracks entity changes - so if you are detaching/attaching entities changes does not get tracked. Now when you try to update the entity back by attaching to context, from context perspective, entity does not have any changes. So SaveChanges does not attempt to save any thing. You have to somehow mark your object as dirty or changed before calling SaveChanges method. Refer this blog post for achieving it. And here's yet another post outlining similar solution.

This is dependant on how your retrieving the Project to be edited. If you getting it out as per your GetProjectById method, then that project entity is having it's changes tracked by the relevant ObjectContext.

From MSDN :

The Entity Framework tracks changes to objects that are attached to an ObjectContext. The Entity Data Model tools generate a pair of partial methods named OnPropertyChanging and OnPropertyChanged. These methods are called in the property setter.

Basically, all you have to do to save changes to a tracked entity is call the SaveChanges() method on the same Object Context that you extracted it from.

I'd recommend looking into using a Repository pattern to manage your ObjectContexts so that you have the correct ObjectContext tracking and saving the changes.

You have two choices. First choice is to share context between GetProjectById and SaveProject. Than your entity will trace changes and you will not need to call Attach. If you want / need to open new context for each operation you have to tell context that Project has been modified. When entity is attached to context it is tracked as Unchanged. You have to manually change entity state to modified by calling ObjectStateManager after attaching:

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

Btw. ObjectContext is disposable so you should handle it by using or try / finally.

Edit:

Based on your comment about WCF first choice is not possible. But you can also check Self Tracking entities (only EF 4.0).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM