C# 如何撤消对自跟踪实体所做的所有更改?

C# 如何撤消对自跟踪实体所做的所有更改?,c#,entity-framework,self-tracking-entities,C#,Entity Framework,Self Tracking Entities,我有一个客户端应用程序,可以通过WCF下载许多STE 使用WPF应用程序,用户可以从列表框中选择一个实体,并通过弹出的UserControl对其进行编辑。由于UserControl直接绑定到对象,因此当用户进行更改时,它当然会影响对象 我想提供一个取消功能,该功能将撤消对实体所做的所有更改 有什么想法吗?您可以保留实体的原始副本。并编辑它的克隆版本。 如果用户取消了更改,您只需继续使用原始副本。我会说,当您在Binding PropertyChanged事件中使用WPF时,请使用键Propert

我有一个客户端应用程序,可以通过WCF下载许多STE

使用WPF应用程序,用户可以从列表框中选择一个实体,并通过弹出的UserControl对其进行编辑。由于UserControl直接绑定到对象,因此当用户进行更改时,它当然会影响对象

我想提供一个取消功能,该功能将撤消对实体所做的所有更改


有什么想法吗?

您可以保留实体的原始副本。并编辑它的克隆版本。

如果用户取消了更改,您只需继续使用原始副本。

我会说,当您在Binding PropertyChanged事件中使用WPF时,请使用键PropertyName和值PropertyValue保存一个字典。在使用反射恢复状态之后

到目前为止,我正在使用这个解决方案 扩展方法

using System.Collections.Generic;
using System.Reflection;

namespace WpfApplication4
{
    public static class EFExtensions
    {
        /// <summary>
        /// Rejects changes made by user
        /// </summary>
        /// <param name="param">Object implementing IObjectWithChangeTracker interface</param>
        public static void RejectChanges(this IObjectWithChangeTracker param)
        {
            OriginalValuesDictionary ovd = param.ChangeTracker.OriginalValues;
            PropertyInfo[] propertyInfos = (param.GetType()).GetProperties();

            foreach (KeyValuePair<string, object> pair in ovd)
            {
                foreach (PropertyInfo property in propertyInfos)
                {
                    if (property.Name == pair.Key && property.CanWrite)
                    {
                        property.SetValue(param, pair.Value, null);
                    }
                }
            }
        }
    }
}

如果您使用EF,这是一个更好的方法。这也是我遵循的方法。这可能是唯一的选择。因为STE不会跟踪所有原始值(就像普通EF实体那样),而其他实体可能会设置回原始值。(ChangeTracker的)原始值字典中只跟踪主键/外键属性,因此当我想保存新更改时,只需将克隆对象备份到线路上即可?是的。那就行了。克隆实体。保留原始实体或克隆作为备份(不太重要)当用户编辑实体时,changetracker将完成其工作(通常在数据绑定场景中),并且您可以通过objectcontext(.ApplyChanges;.SaveChanges)将克隆的实体发送到线路上,以进行持久化。当用户取消其操作时,您将继续使用在编辑操作之前克隆的实体的备份。
using System.Linq;

namespace WpfApplication4
{
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();

            using (var db = new PlatEntities())
            {
                PacketEPD pd = (from epd in db.PacketEPD
                                select epd).First();
                pd.ChangeTracker.ChangeTrackingEnabled = true;
                pd.EDNo = "1";
                pd.RejectChanges();
            }
        }
    }
}