I have a Linq DataContext as a database for the application. I have set up the MVVM pattern and am able to insert new records into the database. However when I load these records and try update them a new instance of the record is being created in the background and being updated with the property changes. So when they UI is invoking the save command the originally loaded instance of the record has no changes and is not saved.
from what I can tell this is the sequence of events
Below is the code I have:
/* This is the Entity */
[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
};
}
}
/* This is the data context */
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;
}
/* This is the View Model */
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));
}
}
}
In your MyDataContext
I would think you want the below instead, a basic singleton concept so that you're working on the same object and thus saving the same object with changes.
private static DataContext context = null;
public static MyDataContext GetContext()
{
if(context == null)
context = new MyDataContext(ConnectionString);
return context;
}
edit- Note, this can have a major impact on your application in the big picture. May need to redesign when a new one is created, and if/when you should specifically set it to null.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With