Windows phone 8 MVVM Linq表在NotifyPropertyChanging上创建新实例

Koe*_*nyn 6 c# linq mvvm windows-phone-8

我有一个Linq DataContext作为应用程序的数据库.我已经设置了MVVM模式,并且能够将新记录插入到数据库中.但是,当我加载这些记录并尝试更新它们时,正在后台创建一个新的记录实例,并使用属性更改进行更新.因此,当UI调用save命令时,最初加载的记录实例没有更改,也不会保存.

据我所知,这是一系列事件

  • 加载实例1
  • 开始更新属性
  • 调用NotifyPropertyChanging
  • 加载了新的instance2
  • 新实例2已更新
  • 从实例1的UI调用保存更改
  • 未进行任何更改,因为实例1尚未更新

以下是我的代码:

/*这是实体*/

[Table]
public class User : IDisposable, INotifyPropertyChanged, INotifyPropertyChanging
{
    private MyDataContext context;

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangingEventHandler PropertyChanging;
    private void NotifyPropertyChanging(String propertyName)
    {
        PropertyChangingEventHandler handler = PropertyChanging;
        if (null != handler)
        {
            handler(this, new PropertyChangingEventArgs(propertyName));
        }
    }

    public void Dispose()
    {
        context.Dispose();
    }

    private Guid _id;
    [Column(IsPrimaryKey = true, IsDbGenerated = false, DbType = "UNIQUEIDENTIFIER NOT NULL", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
    public Guid Id
    {
        get { return _id; }
        set
        {
            if (_id != value)
            {
                NotifyPropertyChanging("Id");
                _id = value;
                NotifyPropertyChanged("Id");
            }
        }
    }

    private string _name;
    [Column(CanBeNull = false)]
    public string Name
    {
        get { return _name; }
        set
        {
            if (_name != value)
            {
                NotifyPropertyChanging("Name"); // This line creates the new entity
                _name = value;
                NotifyPropertyChanged("Name");
            }
        }
    }

    public User()
    {
        this.context = MyDataContext.GetContext();
    }

    public override void SaveChanges()
    {
        if (_id == Guid.Empty)
        {
            this.Id = Guid.NewGuid();
            context.Users.InsertOnSubmit(this);
            context.SubmitChanges();
        }
        else
        {
            context.SubmitChanges();
        }
    }

    public static User NewInstance()
    {
        return new User
        {
            Name = String.Empty
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

/*这是数据上下文*/

public class MyDataContext : DataContext
{
    // Specify the connection string as a static, used in main page and app.xaml.
    public static string ConnectionString = "Data Source=isostore:/MyApp.sdf;Password=pwd";

    public MyDataContext(string connectionString) : base(connectionString) { }

    public static MyDataContext GetContext()
    {
        var context = new MyDataContext(ConnectionString);
        return context;
    }

    public Table<User> Users;
}
Run Code Online (Sandbox Code Playgroud)

/*这是视图模型*/

public sealed class UserViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private User _user;

    public UserViewModel(Guid id)
    {
        using (MyDataContext context = new MyDataContext(MyDataContext.ConnectionString))
        {
            _User = context.User.First(u => u.Id == id);
        }
    }

    public UserViewModel(User user)
    {
        _user = user;
    }

    public UserViewModel()
    {
        _user = User.NewInstance();
    }

    public string Name
    {
        get { return _user.Name; }
        set
        {
            _user.Name = value;
            NotifyPropertyChanged("Name");
        }
    }

    private ICommand _saveCommand;
    public ICommand SaveCommand
    {
        get
        {
            return _saveCommand ?? (_saveCommand = new GenericCommand(() =>
            {
                _user.SaveChanges();
            }, true));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

bla*_*and 2

在你的MyDataContext我认为你想要下面的,一个基本的单例概念,这样你就可以处理同一个对象,从而通过更改保存相同的对象。

private static DataContext context = null;

public static MyDataContext GetContext()
{
    if(context == null)
        context = new MyDataContext(ConnectionString);
    return context;
}
Run Code Online (Sandbox Code Playgroud)

编辑-注意,这可能会对您的应用程序产生重大影响。当创建新的时,以及如果/当​​您应该专门将其设置为 null 时,可能需要重新设计。