insert multiple selected rows into EF

zleug 61 Reputation points
2020-09-02T16:29:56.797+00:00

My WPF form has DataGrid and Save button. The first column of DataGrid is a CheckBox column. I would like when the button is clicked, all row(s) where the CheckBoxe(s) is checked, insert into a EF table. How to do it? I will appreciate for sample.

Thanks.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,692 questions
0 comments No comments
{count} votes

Accepted answer
  1. DaisyTian-1203 11,616 Reputation points
    2020-09-04T02:20:14.757+00:00

    Update AddCommandHandler as below:

    private void AddCommandHandler(object sender, ExecutedRoutedEventArgs e)
            {
                ObservableCollection<Person> LtPeople = new ObservableCollection<Person>();
                if(personDataGrid.SelectedItems.Count>0)
                {
                    foreach (Person p in personDataGrid.SelectedItems)
                    {
                        LtPeople.Add(p);
                    }
                }
                BLL.AddPeople(LtPeople);
            } 
    

    In the BLL , you can add the below code:

    public static class BLL
        {
            public static void AddPeople(ObservableCollection<Person> LtPeople)
            {
                DAL.AddPeople(LtPeople);
            }
        }
    

    In the DAL, you can add the code like below to modify DataBase:

     public static bool AddPeople(ObservableCollection<Person> LtPeople)
            {
                DaisyDBEntities context = new DaisyDBEntities();
                foreach (Person p in LtPeople)
                {
                    context.People.Add(p);
                }
                try
                {
                    context.SaveChanges();
                    return true;
                }
                catch (Exception ex)
                {
                    return false;
                }
            }
    
    0 comments No comments

4 additional answers

Sort by: Most helpful
  1. Peter Fleischer (former MVP) 19,306 Reputation points
    2020-09-03T04:51:23.863+00:00

    Hi,
    try following demo. In demo DataGrid is bound to View with collection of separate data objects (outside EF). The type of data objects used the generated data objects from EF model (Tab1) extended with property for selecting ([Selected]). Save button add selected data to DbSet and execute SaveChanges.

    XAML:

    <Window x:Class="Window055"  
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
            xmlns:local="clr-namespace:WpfApp1.WpfApp055"  
            mc:Ignorable="d"  
            Title="EF add selected rows" Height="450" Width="800">  
      <Window.DataContext>  
        <local:ViewModel/>  
      </Window.DataContext>  
      <Grid>  
        <Grid.RowDefinitions>  
          <RowDefinition/>  
          <RowDefinition Height="auto"/>  
        </Grid.RowDefinitions>  
        <DataGrid ItemsSource="{Binding View}"/>  
        <Button Grid.Row="1" Content="Save" Command="{Binding}"   
                Width="100" HorizontalAlignment="Right" Margin="5"/>  
      </Grid>  
    </Window>  
    

    And code:

    Imports System.Collections.ObjectModel  
    Imports System.ComponentModel  
    Imports System.Data.Entity  
      
    Namespace WpfApp055  
      
      Public Class ViewModel  
        Implements ICommand  
      
        ''' <summary>  
        ''' create demo data in collection for displaying  
        ''' </summary>  
        Public Sub New()  
          Dim rnd As New Random  
          For i = 1 To 10  
            col.Add(New Tab1 With {.[Select] = rnd.NextDouble > 0.5, .Field1 = $"new row {i}"})  
          Next  
          cvs.Source = col  
        End Sub  
      
        Private col As New ObservableCollection(Of Tab1) ' Collection for displaying  
        Private cvs As New CollectionViewSource ' View source for displaying  
      
        ''' <summary>  
        ''' View for displaying data  
        ''' </summary>  
        ''' <returns></returns>  
        Public ReadOnly Property View As ICollectionView  
          Get  
            Return cvs.View  
          End Get  
        End Property  
      
        ' Managing Save command  
        Public Event CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged  
        Public Sub Execute(parameter As Object) Implements ICommand.Execute  
          ' Save selected data  
          Using ctx As New Database1Entities1 ' data context  
            ctx.Tab1.AddRange(col.Where(Function(d1 As Tab1)  
                                          Return d1.Select  
                                        End Function)) ' add all selected rows  
            ctx.SaveChanges()  
          End Using  
        End Sub  
        Public Function CanExecute(parameter As Object) As Boolean Implements ICommand.CanExecute  
          Return True  
        End Function  
      End Class  
      
      ''' <summary>  
      ''' actual data context  
      ''' </summary>  
      Partial Public Class Database1Entities1  
        Inherits DbContext  
        Public Sub New()  
          MyBase.New("name=Database1Entities")  
        End Sub  
        Public Overridable Property Tab1() As DbSet(Of Tab1) ' Tab1 from entity model  
      End Class  
    End Namespace  
      
    ''' <summary>  
    ''' add column to entity for select in DataGrid  
    ''' </summary>  
    Partial Public Class Tab1  
      Public Property [Select] As Boolean  
    End Class  
    

    And in Csharp:

    using System;  
    using System.Collections.ObjectModel;  
    using System.ComponentModel;  
    using System.Linq;  
    using System.Windows;  
    using System.Windows.Data;  
    using System.Windows.Input;  
    using WpfApp1;  
      
    namespace WpfApp1  
    {  
      /// <summary>  
      /// Interaction logic for Window79.xaml  
      /// </summary>  
      public partial class Window79 : Window  
      {  
        public Window79()  
        {  
          InitializeComponent();  
        }  
      }  
      
      public partial class Tab1  
      {  
        public bool Select { get; set; }  
      }  
    
      public class ViewModel: ICommand  
      {  
        /// <summary>  
        /// create demo data in collection for displaying  
        /// </summary>  
        public ViewModel()  
        {  
          Random rnd = new Random();  
          for (int i = 0; i < 10; i++)  
            col.Add(new Tab1() {Select = rnd.NextDouble() > 0.5, Id=i, Field1 = $"new row {i}"});  
          cvs.Source = col;         
        }  
        private ObservableCollection<Tab1> col = new ObservableCollection<Tab1>(); // Collection for displaying  
        private CollectionViewSource cvs = new CollectionViewSource(); // View source for displaying  
      
      
        /// <summary>  
        /// View for displaying data  
        /// </summary>  
        /// <returns></returns>  
        public ICollectionView View { get => cvs.View; }  
      
        // Managing Save command  
        public void Execute(object parameter)  
        {  
          // Save selected data  
          using (Database1Entities ctx = new Database1Entities()) // data context  
            {  
            ctx.Tab1.AddRange(col.Where((Tab1 d1) => d1.Select)); // add all selected rows  
            ctx.SaveChanges();  
          }  
        }  
        public event EventHandler CanExecuteChanged;  
        public bool CanExecute(object parameter) => true;  
      }  
    }  
    

    22675-x.gif

    0 comments No comments

  2. DaisyTian-1203 11,616 Reputation points
    2020-09-03T07:32:37.943+00:00

    I refer to document Create a simple data application with WPF and Entity Framework 6 to make my demo for your problem.
    I use the below code in cs to add models which are selected in the DataGrid:

     private void AddCommandHandler(object sender, ExecutedRoutedEventArgs e)  
            {  
                 
                foreach(Person  p in personDataGrid.SelectedItems)  
                {  
                    context.People.Add(p);  
                }  
                context.SaveChanges();  
      
            }  
    

    You should make SelectionUnit="FullRow" SelectionMode="Extended" for your DataGrid to make it can be selected in multiple rows.
    22323-capture.png

    The below is my result picture:
    22336-4.gif

    Here is my code for the demo


  3. zleug 61 Reputation points
    2020-09-07T05:29:12.22+00:00

    Hi DaisyTian-MSFT. Thanks to try to help.
    In your code for AddCommandHandler

             BLL.AddPeople(LtPeople);
    

    you pass selected rows to BL layer. But when try use your code I got error message:
    The type 'People' is defined in an assembly that is not referenced. You must add a reference to assembly 'MyProject.DL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'

    How to fix this error?

    Thanks.

    0 comments No comments

  4. zleug 61 Reputation points
    2020-09-08T22:01:52.027+00:00

    Hi DaisyTian-MSFT thanks for your help. I found solution for that problem,

    0 comments No comments