简体   繁体   中英

Save VM properties with EF code first

I thought this would be simple but can't find any good examples.

public Class BookVm : ImplementsPropertyChanged
{
    public int BookId {get;set;}
    private bool _favorite;
    public bool Favorite
    { 
        get { return _favorite; }
        set {
                _favorite = value;
                OnPropertyChanged("Favorite");
               MyDbContext.SaveChanges() // this does not work
        }
    }

Then in my XAML bound to Book

<CheckBox Content="Favorite" IsChecked="{Binding Favorite}" />

How and when do I call SaveChanges() on my DatabaseContext?

I don't want to implement a save button. If I intercept the PropertyChange event and call SaveChanges, nothing seems to happen. My object is modified in memory but the database does not see a change.

My BookVm class is created on application startup like so:

        foreach (var book in MyDbContext.Books)
            Books.Add(book);

Where Books is an ObservableCollection<Book> in my MainWindowVm

Say you had a dataservice class which returns book and update a book:

 public class DataService
{
    public static void UpdateBook(Book book)
    {
        //Call the context to update the database
    }

    public static IEnumerable<Book> FetchBooks()
    {
        // return DBContext.GetBooks
    }
}

Now You can make a View Model which takes a book and then return the properties. BookId is not going to change as per database(if it is a primary key).

//Domain Object
public class Book
{
    public int BookId { get; set; }
    public bool Favourite { get; set; }
}

//View Model
public class BookVm : ImplementsPropertyChanged
{
    private readonly Book book;

    //Store the book
    public BookVm(Book book)
    {
        this.book = book;
    }

    private bool favorite;
    public int BookId
    {
        get { return book.BookId; }
    }

    public bool Favorite
    {
        get { return favorite; }
        set
        {
            if (favorite != value)
            {
                favorite = value;
                //Update the database 
                UpdateDatabase();
            }
        }
    }

    private void UpdateDatabase()
    {
        //set the favorite value of the domain book
        book.Favourite = favorite;
        DataService.UpdateBook(book);
    }
}

We are storing the domain object in the ViewModel for later user. We can also write a controller that will display the view like this:

public class BookController
{
    public void Display()
    {
        IEnumerable<Book> books = DataService.FetchBooks();
        ObservableCollection<BookVm> bookVms = new ObservableCollection<BookVm>();
        foreach (var book in books)
        {
            BookVm bookVm = new BookVm(book);
            bookVms.Add(bookVm);
        }
        //Get the View and then bind using the bookVms collection
    }
}

If you want to save the changes of the property Favorite you have to subscribe to the property changed event and then save the value to the DB.

Here you can find a link with information about subscription to property changed event

Edit Here are an example from MSDN

Also guessing that you have similar code in the Implements property change.

public class ImplementsPropertyChanged : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
} 

You will also need to add the following to raise the notifications.

public bool Favorite
    {
        get { return favorite; }
        set
        {
            if (favorite != value)
            {
                favorite = value;
                //Update the database 
                UpdateDatabase();
                OnPropertyChanged("Favorite");
            }
        }
    }

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