WPF MVVM Сохранить изменения DataGrid в базу данных
всем. Подскажите пожалуйста как мне сохранить изменения, которые происходят в DataGrid, в базу данных. Использую EF. ПО подходу у меня DataBaseFirst. Так же я изучаю еще mvvm, поэтому если будет возможность распишите поподробнее. Для отображения в DataGrid я использую ObservableCollection<>, я так же понимаю что нужно подписаться на событие CollectionChanged. Но не понимаю как это сделать. Model, ViewModel, View прикладываю.
Model: InfoDrill
public partial class InfoDrill
{
public int Uid { get; set; }
/// <summary>
/// № скважины
/// </summary>
public string? HoleId { get; set; }
/// <summary>
/// Тип выработки
/// </summary>
public int? TypeLcode { get; set; }
/// <summary>
/// Название участка
/// </summary>
public int? PlaceSite { get; set; }
/// <summary>
/// Номер ПЛ
/// </summary>
public double? Profile { get; set; }
/// <summary>
/// Долгота
/// </summary>
public double? Easting { get; set; }
/// <summary>
/// Широта
/// </summary>
public double? Northing { get; set; }
/// <summary>
/// Абс. отм.
/// </summary>
public double? Elevation { get; set; }
/// <summary>
/// Диаметр бурения, мм
/// </summary>
public double? Diam { get; set; }
/// <summary>
/// Азимут ист., °
/// </summary>
public double? Azimuth { get; set; }
/// <summary>
/// Угол наклона от горизонта, °
/// </summary>
public double? Dip { get; set; }
/// <summary>
/// Глубина скважины,м
/// </summary>
public double? Depth { get; set; }
/// <summary>
/// Уровень ПВ, м
/// </summary>
public double? Uroven { get; set; }
/// <summary>
/// Абс. отм. уровня, м
///
/// </summary>
public double? UrAbs { get; set; }
/// <summary>
/// Начало бурения
/// </summary>
public DateOnly? StartDate { get; set; }
/// <summary>
/// Окончание бурения
/// </summary>
public DateOnly? EndDate { get; set; }
/// <summary>
/// Геолог
/// </summary>
public int? Geolog { get; set; }
/// <summary>
/// Примечания
/// </summary>
public string? NotesCommentsText { get; set; }
public int Project { get; set; }
public virtual Person? GeologNavigation { get; set; }
public virtual Place? PlaceSiteNavigation { get; set; }
public virtual Project ProjectNavigation { get; set; } = null!;
public virtual ICollection<Rock> Rocks { get; set; } = new List<Rock>();
public virtual Mine? TypeLcodeNavigation { get; set; }
}
Данный класс мне создался автоматом, когда подключался к БД PostgreSQL
ViewModel
internal class Info_DrilModel : ViewModelBase
{
private NavigationManager navigationManager;
private AnzasContext dbcontext;
private ObservableCollection<InfoDrill> _infodrill;
/// <summary>
/// Информаиция по скважинам
/// </summary>
public ObservableCollection<InfoDrill> InfoDrills
{
set => Set(ref _infodrill, value);
}
/// <summary>
/// Выбранный элемент скважин
/// </summary>
private InfoDrill? _selectedInfodril;
public InfoDrill? Selected_InfoDrill
{
get => _selectedInfodril;
set => Set(ref _selectedInfodril, value);
}
public Info_DrilModel(NavigationManager navigationManager, AnzasContext db)
{
this.navigationManager = navigationManager;
this.dbcontext = db;
InfoDrills = new ObservableCollection<InfoDrill>();
InfoDrills = dbcontext.InfoDrills
.Include(p => p.PlaceSiteNavigation)
.Include(item => item.TypeLcodeNavigation)
.Include(item => item.GeologNavigation)
.AsNoTracking().ToObservableCollection();
}
}
View
<DataGrid Margin="20"
ItemsSource="{Binding InfoDrills , Mode=OneWay }"
AutoGenerateColumns="False"
CanUserReorderColumns="True"
IsReadOnly="{Binding IsReadOnlyData}">
<DataGrid.Columns>
<DataGridTextColumn Header="№ скважины"
Binding="{Binding HoleId}"
MinWidth="120"
Width="20"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference HoleIdCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Тип выработки"
Binding="{Binding TypeLcodeNavigation.TypeLcode }"
MinWidth="180"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference TypeLcodeCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Название участка"
Binding="{Binding PlaceSiteNavigation.NamePlaceSite}"
MinWidth="160"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference PlaceSiteCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Номер ПЛ"
Binding="{Binding Profile}"
MinWidth="120"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference ProfileCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Долгота"
Binding="{Binding Easting}"
MinWidth="120"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference EastingCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Широта"
Binding="{Binding Northing}"
MinWidth="120"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference NorthingCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Абс. отм."
Binding="{Binding Elevation}"
MinWidth="120"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference ElevationCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Диаметр бурения,мм"
Binding="{Binding Diam}"
MinWidth="180"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference DiamCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Азимут ист.°"
Binding="{Binding Azimuth}"
MinWidth="160"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference AzimuthCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Угол наклона от горизонта,°"
Binding="{Binding Dip}"
MinWidth="220"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference DipCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Глубина скважины,м"
Binding="{Binding Depth}"
MinWidth="180"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference DepthCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Уровень ПВ, м"
Binding="{Binding Uroven}"
MinWidth="140"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference UrovenCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Абс. отм. уровня, м"
Binding="{Binding UrAbs}"
MinWidth="160"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference UrAbsCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Начало бурения"
Binding="{Binding StartDate}"
MinWidth="140"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference StartDateCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Окончание бурения"
Binding="{Binding EndDate}"
MinWidth="160"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference EndDateCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Геолог"
Binding="{Binding GeologNavigation.Surname }"
MinWidth="120"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference GeologCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn Header="Примечания"
Binding="{Binding NotesCommentsText}"
MinWidth="120"
Width="*"
CellStyle="{StaticResource CenterGridCell}"
Visibility="{Binding Source={x:Reference NotesCheked},
Path=IsChecked,
Converter={StaticResource BooleanToVisibilityConverter}}" />
</DataGrid.Columns>
ViewModelBase
internal abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? PropertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
protected virtual bool Set<T>(ref T field, T value, [CallerMemberName] string? PropertyName = null)
{
// Если значение поля которое хотим обновить уже соответсвует тому значение которое мы передали возвращаем ложь
if (Equals(field, value)) return false;
field = value;
OnPropertyChanged(PropertyName);
return true;
}
}