locked
Updating Navigation Properties RRS feed

  • Question

  • Hi,

    I've created a database with following tables:

    Volunteer:

       Title_Id

    Title:

       Title_Id

       Title_Name

     

    Generating an Entity Model from this gives me:

    Volunteer:

       Title_Id

       Title (Navigation property)

    Title

       Title_Id

       Title_Name

       Volunteers (Navigation property)

     

    This is great but in my client I have bound a dropdown box to the Titles collection and the SelectedItem to an instance of Volunteer.Title with two-way binding so that if the selected value changes the underlying Volunteer object is updated. This all works fine for existing Volunteer records when I save the DataContext.

    The problem is when I create a new Volunteer and add it to the DataContext. If I then try and change the Title I get an error because Volunteer.Title_Id is not updated even though Volunteer.Title is. So the navigation property is succesfully updated but the actual Title_Id field is not.

    Does anyone have any idea how I should be doing this?

    Wednesday, July 21, 2010 1:55 PM

Answers

  • Pratik,

    Thanks for your reply, I am actually finding the problem with pre-existing Volunteer records.

    However I have overcome it simply by not generating Foreign Key fields in the Entity Model, therefore the Foreign Key field isn't written back to the server on updating.

    You can set this when Generating Model from Database, look for a checkbox in the dialog.

    Regards,

    Neil

    • Marked as answer by NeilAlderson Thursday, July 22, 2010 9:18 PM
    Thursday, July 22, 2010 9:18 PM

All replies

  • This is the data bound ComboBox:

    <ComboBox x:Name="Title" Grid.Column="1" Grid.Row="0" VerticalAlignment="Center" DisplayMemberPath="Title_Name" ItemsSource="{Binding Titles}" SelectedItem="{Binding CurrentVolunteer.Title, Mode=TwoWay}"></ComboBox>

    This is my ViewModel:

    public class VolunteerDetailsViewModel : ViewModelBase
      {
        private RBC1aDatabase _dataContext;
    
        private bool _canSave;
    
        public VolunteerDetailsViewModel(RBC1aDatabase dataContext, IEventAggregator eventAggregator)
        {
          _dataContext = dataContext;
          VolunteerSelectedEvent = eventAggregator.GetEvent<VolunteerSelectedEvent>();
          VolunteerSelectedEvent.Subscribe(VolunteerChanged);
    
          NewCommand = new DelegateCommand<object>(CreateNew, CanCreate);
          SaveCommand = new DelegateCommand<object>(Save, CanSave);
          DeleteCommand = new DelegateCommand<object>(Delete);
        }
    
        #region Events
    
        public VolunteerSelectedEvent VolunteerSelectedEvent { get; set; }
    
        public void VolunteerChanged(Volunteer volunteer)
        {
          CurrentVolunteer = volunteer;
        }
    
        #endregion
    
        #region Commands
    
        public DelegateCommand<object> NewCommand { get; set; }
        public DelegateCommand<object> SaveCommand { get; set; }
        public DelegateCommand<object> DeleteCommand { get; set; }
    
        private void CreateNew(object param)
        {
          Volunteer newVolunteer = new Volunteer();
          newVolunteer.Firstname = "New";
          newVolunteer.Surname = "New";
    
          _dataContext.AddToVolunteers(newVolunteer);
          CurrentVolunteer = newVolunteer;
        }
    
        private bool CanCreate(object args)
        {
          return true;
        }
    
        private bool CanSave(object args)
        {
          return _canSave;
        }
    
        private void Save(object param)
        {
          _dataContext.SaveChanges(SaveChangesOptions.Batch);
    
          _canSave = false;
          SaveCommand.RaiseCanExecuteChanged();
        }
    
        private void Delete(object param)
        {
          _dataContext.DeleteObject(_currentVolunteer);
          _dataContext.SaveChanges(SaveChangesOptions.Batch);
    
          _canSave = false;
          SaveCommand.RaiseCanExecuteChanged();
        }
    
        #endregion
    
        #region Properties
    
        private Volunteer _currentVolunteer;
        public Volunteer CurrentVolunteer
        {
          get
          {
            return _currentVolunteer;
          }
    
          set
          {
            if (_currentVolunteer != null)
            {
              _currentVolunteer.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(_currentPerson_PropertyChanged);
            }
    
            _currentVolunteer = value;
    
            if (_currentVolunteer != null)
            {
              _currentVolunteer.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(_currentPerson_PropertyChanged);
            }
    
            base.OnPropertyChanged("CurrentVolunteer");        
          }
        }
    
        void _currentPerson_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {      
          _dataContext.UpdateObject(_currentVolunteer);
    
          _canSave = true;
          SaveCommand.RaiseCanExecuteChanged();
        }
    
        public IEnumerable<Title> Titles { get { return _dataContext.Titles; } }
    
        #endregion
      }

    Wednesday, July 21, 2010 2:04 PM
  • Quick question:

    So you create a new instance of Volunteer and then add it to the context. Do you call SaveChanges, before you try to change the Title id?

    If yes, then since titleId is the key, it cannot be changed. You will have to delete the volunteer and create a new one with the new title id or say a seperate key for volunteer, which is constant for the lifetime of that instance.

    Hope this helps.
    Thanks

    Pratik


    This posting is provided "AS IS" with no warranties, and confers no rights.
    Thursday, July 22, 2010 5:44 PM
    Moderator
  • Pratik,

    Thanks for your reply, I am actually finding the problem with pre-existing Volunteer records.

    However I have overcome it simply by not generating Foreign Key fields in the Entity Model, therefore the Foreign Key field isn't written back to the server on updating.

    You can set this when Generating Model from Database, look for a checkbox in the dialog.

    Regards,

    Neil

    • Marked as answer by NeilAlderson Thursday, July 22, 2010 9:18 PM
    Thursday, July 22, 2010 9:18 PM