Jak zrobić edycję i usuwanie rekordu w MVVM C# i LINQ

0

Witam serdecznie,

Wiecie może jak zrobić przykład edycji i zapisu rekordu w tabeli ?

Kod poniżej:
Warstwa View

 
<DataGrid AutoGenerateColumns="False" AlternationCount="2" ItemsSource="{Binding Lista}" SelectedItem="{Binding WybranyObiekt}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="NR" Binding="{Binding IdWydania}"/>
                <DataGridTextColumn Header="KOD TOWARU" Binding="{Binding TowaryWMagazynieKodTowaru}"/>
                <DataGridTextColumn Header="NAZWA TOWARU" Binding="{Binding TowaryWMagazynieNazwaTowaru}"/>
                    <DataGridTextColumn Header="ILOŚĆ" Binding="{Binding Ilosc}"/>
                    <DataGridTextColumn Header="UWAGI" Binding="{Binding Uwagi}"/>
                <DataGridTextColumn Header="DOKUMENT ZATWIERDZONY?" Binding="{Binding Zatwierdzony}"/>
            </DataGrid.Columns>
        </DataGrid>

Warstwa ViewModel

 
 public class WydanieZewnetrzneViewModel:WszystkieViewModel<WydanieZewnetrzneForAllView>
  {
      #region Konstruktor
      public WydanieZewnetrzneViewModel()
            :base()
        {
            base.DisplayName = "Wydanie Zewnętrzne (WZ)";
        }
      #endregion Konstruktor

      #region Helpers
      public override void load()
      {
          Lista = new ObservableCollection<WydanieZewnetrzneForAllView>
          (
            from wydanieZewnetrzne in fakturyEntities.WydanieZewnetrzne
            select new WydanieZewnetrzneForAllView
            {
                IdWydania = wydanieZewnetrzne.IdWydania,
                TowaryWMagazynieKodTowaru = wydanieZewnetrzne.TowaryWMagazynie.KodTowaru,
                TowaryWMagazynieNazwaTowaru = wydanieZewnetrzne.TowaryWMagazynie.NazwaTowaru,
                Ilosc = wydanieZewnetrzne.Ilosc,
                DataOperacji = wydanieZewnetrzne.DataOperacji,
                Uwagi = wydanieZewnetrzne.Uwagi,
                Zatwierdzony = wydanieZewnetrzne.Zatwierdzony
            }
          );
      }
     
      public override void delate()
      { 
        var kasowany = WybranyObiekt;
        //fakturyEntities.WydanieZewnetrzne.Remove(kasowany); - tutaj nie wiem jak powinno wyglądać zapytanie linqu?
        fakturyEntities.SaveChanges();
        Lista.Remove(kasowany);      
         
      }
      public override void edit()
      {
       // W tym miejscu nie wiem jak edytować dany rekord - zapytanie Linqu lub inna metoda
      }
     
      #endregion Helpers
  }
}

Klasa WszystkieViewModel

 public abstract class WszystkieViewModel<T> :DataBaseViewModel 
    // <T> - Typ generyczny - Dziedziczenie po klasie zakładek.
    {
        #region Fields
       
                private ObservableCollection<T> _Lista;
        //Typ <T> Abstrakcyjny typ czego to jest lista T różne rzeczy z klas dziedziczących.
       
        private BaseCommand _DelateCommad;
        private BaseCommand _EditCommand;
           
        #endregion //Fields

        #region Propertis
        private T _wybranyObiekt;
        public T WybranyObiekt
        {
            get
            {
                return _wybranyObiekt;
            }
            set
            {
                _wybranyObiekt = value;
                // tu obsługa PropertyChanged etc.
            }
        }

       
        public ICommand DelateCommand  
        {
            get
            {
                if (_DelateCommad == null)
                    _DelateCommad = new BaseCommand(delate);
                return _DelateCommad;
            }
        }
        public ICommand EditCommand
        {
            get
            {
                if (_EditCommand == null)
                    _EditCommand = new BaseCommand(edit);
                return _EditCommand;
            }
        }
       
        public ObservableCollection<T> Lista
        {
            get
            {
                if (_Lista == null)
                    load();
                return _Lista;
            }
            set
            {
                _Lista = value;
                OnPropertyChanged(() => Lista);
            }
        }
      
    
        #endregion Propertis

   
        #region Helpers
            
        public abstract void delate();
        public abstract void edit();
       
      
      
        #endregion //Helpers
    }
}


klasa WydanieZewnetrzneForAllView

 public class WydanieZewnetrzneForAllView
    {
        public int IdWydania { get; set; }
        public string TowaryWMagazynieKodTowaru { get; set; }
        public string TowaryWMagazynieNazwaTowaru { get; set; }
        public decimal Ilosc { get; set; }
        public DateTime DataOperacji { get; set; }
        public string Uwagi { get; set; }
        public bool Zatwierdzony { get; set; }

    }
}
0

Pisząc LINQU masz na myśli Entity Framework?

0

Witam,
Zapytanie Linq - technologię którą opracował Microsoft do odpytywania bazy danych zamiast SQL np.

 private void button22_Click(object sender, EventArgs e)
        {
            TestLinqEntities baza = new TestLinqEntities();
            //Wybieramy pierwszego pracownika który zarabia więcej
            //niż 1000 zł i wyświetlamy jego nazwisko.
            label1.Text =
               (
                   from pracownik in baza.Pracownicy
                   select new
                   {
                       pracownik.nazwisko,
                       pracownik.placaNetto
                   }
               ).First(p=>p.placaNetto>1000).nazwisko.ToString(); 
        }

Zapytania Linq są mniej skąplikowane niż zapytania SQL i krótsze jedyną wadą jest szybkość działania.
W rozwiązaniu może być także czysty kod C# -metody.

0

Witaj,

Zazwyczaj w oparciu o kontekst danych oznacza się rekord/rekordy jako zmodyfikowane, a następnie wywołuje SaveChanges.

db.Foo.Attach(updatedFoo);
db.Entry(updatedFoo).State = EntityState.Modified;
db.SaveChanges();

Coś w ten deseń...

Pozdrawiam,
Maciej

0

Mało czytelne jest dla mnie to co napisałeś.

0

Ale czego nie rozumiesz? To są podstawowe operacje w EF...

0

Jak powinno wyglądać zapytaniu Linq w odniesieniu do projektu?

1

Chyba jesteś pod wrażeniem LINQ bo Ci się ze wszystkim to LINQ kojarzy :) Twój kod nie jest zapytaniem LINQ, jest zaś wywołaniem metod udostępnianych przez Entity Framework.

Można również tak:

using (var db = new DataContext())
{
                    
}

M.

0

A mozesz mi napisać jak bedzie wygladac usuwanie i edycja wygladało w odniesieniu do kodu który dodałem powyżej
public class WydanieZewnetrzneViewModel:WszystkieViewModel<WydanieZewnetrzneForAllView>

Pierwszy raz to robię w życiu dlatego potrzebuję pomocy.
PS. Nie musi być to zapytanie Linq może być czysty kod C# - odpowiednia metoda.

Pozdrawiam,

0

Niestety nie napiszę jak to wyglądać będzie w Twoim kodzie. Podstawowe operacje EF nie są trudne, ale niestety trzeba to wszystko przerobić na własnym przykładzie (https://www.google.pl/#q=c%23+ef+crud). Czy ten kod który usunąłeś edycją:

public override void edit()
      {
       fakturyEntities.WydanieZewnetrzne.Attach(updatedWydanieZewnetrzne);
       fakturyEntities.Entry(updatedWydanieZewnetrzne).State = EntityState.Modified;
       fakturyEntities.SaveChanges();      }
      }

nie zapisał zmian? Miałeś jakiś błąd?

M.

0

updatedWydanieZewnetrzne się świeci ponieważ updatedWydanieZewnetrzne nie jest nigdzie zdefiniowane - próbowałem podstawić.

public override void edit()
      {
       var modyfikowany = WybranyObiekt;
       fakturyEntities.WydanieZewnetrzne.Attach(modyfikowany);
       fakturyEntities.Entry(modyfikowany).State = EntityState.Modified;
       fakturyEntities.SaveChanges();      }
      }

wtedy nie ma błędu ale nie działa.

0

I ten WybranyObiekt zawiera zmiany? Może dlatego nie działa bo faktycznie nic się w nim nie zmieniło... Sprawdź jakąś właściwość, której wyraźnie nadasz nową wartość w WybranyObiekt czy wywołanie edit (nie lepiej nazwać: Update?) nie spowoduje zapisania informacji w bazie? Swoją drogą zdecyduj się... Albo stosuj rodzime nazwy albo angielskie. Takie przemieszanie wprowadza bałagan :)

M.

Delate (https://translate.google.pl/?hl=pl&tab=wT#en/pl/Delate) to nie to samo co Delete

0

masz rację delate zmieniłem wszedzie na remove.

natomiast z wybranym obiektem działa mi usuwanie w klasach z typem generycznym np <TypPlatnosci> natomiast

public override void remove()
       {
           var kasowany = WybranyObiekt;
          // fakturyEntities.TypyAdresow.Remove(kasowany); - w tej linii jest błąd konwersji przy <WydanieZewnetrzneForAllView>
           fakturyEntities.SaveChanges();
           Lista.Remove(kasowany);
       }

W załączniku zamiesiłem jak to wygląda w Visual Studio

0

Zanim przedstawisz kolejny problem możesz ustosunkować się do zapisywania zmodyfikowanych rekordów w bazie? Udało Ci się zapisać zmiany? Jak Twoja metoda Edit/Update? Działa?

M.

#Tip: w C# nazwy metod warto zaczynać Wielką literą.

0

Niestety edycja rekordu nie działa. Do projektu potrzebuję zrobić edycję wybranego rekordu zapisanego wcześniej do bazy danych oraz usuwanie rekordu - to drugie działa mi w połowie. To znaczy działa w tych klasach gdzie jest dziedziczenie po np. WszystkieViewModel<Rejon_Kontrahenta> natomiast nie działa w klasach dziedziczących po ForAllView np. :WszystkieViewModel<WydanieZewnetrzneForAllView>

0

Nie ma błędu, jedna z właściwości WybranyObiekt została zmieniona i metoda zapisu zmodyfikowanych danych nie działa? Niestety nie wiem jak Ci pomóc.
M.

0

A usunięcie danego rekordu? Jak powinna wyglądać linia w której wyskakuje błąd?

0

Stosujesz typy generyczne i nie wiesz co to jest błąd konwersji (https://www.google.pl/#q=c%23+b%C5%82%C4%85d+konwersji)? Widać WydanieZewnetrzneForAllView to coś innego niż WydanieZewnetrzne (EntitiesForView, a Entities).
M.

0

Wiem co to błąd konwersji tylko nie wiem jak powinno wyglądać rzutowanie w tym wypadku.

0

Jezeli chodzi o edycję danego rekordu zaproponowany kod przez ciebie wyglada tak i niestety nie działa edycja:

  
 public abstract class WszystkieViewModel<T> :DataBaseViewModel
    // <T> - Typ generyczny - Dziedziczenie po klasie zakładek.
    {
        #region Fields
      
              private ObservableCollection<T> _Lista;
        //Typ <T> Abstrakcyjny typ czego to jest lista T różne rzeczy z klas dziedziczących.
       
        private BaseCommand _RemoveCommad;
        private BaseCommand _EditCommand;
           
        #endregion //Fields

        #region Propertis
        private T _wybranyObiekt;
        public T WybranyObiekt
        {
            get
            {
                return _wybranyObiekt;
            }
            set
            {
                _wybranyObiekt = value;
                // tu obsługa PropertyChanged etc.
            }
        }

      
        public ICommand RemoveCommand  
        {
            get
            {
                if (_RemoveCommad == null)
                    _RemoveCommad = new BaseCommand(remove);
                return _RemoveCommad;
            }
        }
        public ICommand EditCommand
        {
            get
            {
                if (_EditCommand == null)
                    _EditCommand = new BaseCommand(edit);
                return _EditCommand;
            }
        }
       
        public ObservableCollection<T> Lista
        {
            get
            {
                if (_Lista == null)
                    load();
                return _Lista;
            }
            set
            {
                _Lista = value;
                OnPropertyChanged(() => Lista);
            }
        }
     
       
       
      
        //end 2 
        #endregion Propertis

    
        #region Helpers
       
       
 
        public abstract void remove();
        public abstract void edit();


        #endregion //Helpers
    }
}
 
 

Warstwa ViewModel

public class RejonKontrahentaViewModel:WszystkieViewModel<Rejon_Kontrahenta>
  {
      #region Konstruktor
      public RejonKontrahentaViewModel()
        :base()
        {
            base.DisplayName = "Rejon Kontrahenta"; 

        }
      #endregion //Konstruktor
      #region Helpers
      public override void load()
      {
          Lista = new ObservableCollection<Rejon_Kontrahenta>
          (
          from rejonKontrahenta in fakturyEntities.Rejon_Kontrahenta
          orderby rejonKontrahenta.NazwaRejonu
          select rejonKontrahenta
          );
      }
    
      public override void remove()
      {
          var kasowany = WybranyObiekt;
          fakturyEntities.Rejon_Kontrahenta.Remove(kasowany);
          fakturyEntities.SaveChanges();
          Lista.Remove(kasowany);
      }

     public override void edit()
      {
       var modyfikowany = WybranyObiekt;
       fakturyEntities.Rejon_Kontrahenta.Attach(modyfikowany);
       fakturyEntities.Entry(modyfikowany).State = EntityState.Modified;
       fakturyEntities.SaveChanges();      
      }
      #endregion //Helpers
  }
}

 
0

Sądzę że gdzieś masz przekombinowaną sprawę tak ogółem. Jak nie wiesz to może utwórz nowy obiekt i poustawiaj poszczególne właściwości?
M.

0

A nie można wyciągnąć w metodzie nadpisującej edycji po Id klucza z bazy?

0

Ma ktoś pomysł jaką metodę nadpisującą można wykorzystać do usuwania i edycji rekordu?

0

Zrobiłem wyszukiwanie po Id i działa.

  var kasowany = fakturyEntities.Adresy.Find(WybranyObiekt.IdAdresu);
              fakturyEntities.Adresy.Remove(kasowany);
              fakturyEntities.SaveChanges();
              Lista.Remove(WybranyObiekt); 

Problem mam z Widokami w których wykorzystałem już na okno modalne właściwość SelectedItem i mam dodane już np. do okna modalnego SelectedItem="{Binding Path=WybranyAdres, Mode=TwoWay}"> - nie mogę dodać SelectedItem="{Binding WybranyObiekt}"> Czy jest może jaka właściwość w Visual Studio która działa jak SelectedItem, do której mógłbym zbindować WybranyObiekt?

0

A co mają właściwości VS do Twojego kodu?

0

Chodzi mi o to że w DataGrid wykorzystałem już SelectedItem i potrzebuję opcję która po wybraniu danego rekordu w programie odniesie się do propertisa WybranyObiekt. Drugi raz SelectedItem nie mogę zastosować.

0

Kod poniżej działa zależnie od tego co się wpisze w nazwie.

 public override void edit()
      {
          var modyfikowany = fakturyEntities.TypPlatnosci.Find(WybranyObiekt.IdTypPlatnosci);
          modyfikowany.Nazwa = "Gotówka";
          fakturyEntities.SaveChanges();
          
      } 

natomiast mam pytanie jak się odnieść do edycji danego rekordu w widoku? Chodzi mi o to żeby przechodziło do widoku z edytowanym rekordem (w tym wypadku NowyTypPlatnosciView spiętej z NowyTypPlatnosciViewModel) w którym będę mógł dokonać zmian i zapisać powtórnie rekord.

0

WybranyAdres to całkiem inna właściwość wykorzystywana do pobrania danych z okna modalnego

1 użytkowników online, w tym zalogowanych: 0, gości: 1