Сохранение отредактированного объекта в Entity Framework - PullRequest
2 голосов
/ 06 сентября 2010

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

 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();
        }

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

Это моя сущность:

    [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
}

Ответы [ 3 ]

3 голосов
/ 06 сентября 2010

EF Context отслеживает изменения сущностей - поэтому, если вы отсоединяете / присоединяете сущности, изменения не отслеживаются. Теперь, когда вы пытаетесь обновить сущность обратно, присоединяя к контексту, с точки зрения контекста, сущность не имеет никаких изменений. Таким образом, SaveChanges не пытается сохранить что-либо. Вы должны как-то пометить свой объект как грязный или измененный перед вызовом метода SaveChanges. Обратитесь к этому сообщению в блоге для достижения этого. И вот еще один пост с изложением аналогичного решения.

1 голос
/ 06 сентября 2010

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

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

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

Edit:

Исходя из вашего комментария о WCF, первый выбор невозможен. Но вы также можете проверить объекты «Самопроверка» (только EF 4.0).

1 голос
/ 06 сентября 2010

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

С MSDN :

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...