DataGridView - insert danych do bazy

0

Cześć wszystkim

Mam Datagridview, który jest oparty o tableadapter pobierający dane z czterech tabel bazy danych.
Visual nie pozwala mi na zmianę flagi GenerateDBDirectMethods na true w tableadapter, prawdopodobnie z powodu użycia wielu tabel. Co a tym idzie nie mogę wywołać instrukcji Insert aby poprzez tableadapter wrzucić rekord do bazy. Chodzi mi tutaj oczywiście o insert tylko do jednej z tych czterech tabel. Postałe to słowniki.

Na formie pod gridem mam kontrolki i przycisk po którego naciśnięciu ma mi się dodać rekord w bazie danych wraz z odświeżeniem danych w gridzie.

Czy tableadapter kompleksowo obsłuży mi (w sensie insert, delete) tylko datatable opartego o jedną tabelę? A może jest jeszcze jakiś haczyk?
Gdzieś wyczytałem na jakimś forum że można obejść ten problem dodając datatable z jedna tabela, a potem w jakiś czarodziejski sposób podmienić mu składnię sql i wtedy insert się wykona :)

Nie upieram się przy żadnym rozwiązaniu. Podpowiedzcie proszę jak powinno się robić taki mechanizm który zbiera dane z kontrolek i dodaje rekord do tabeli bazy danych aby był jak najbardziej czytelny i nie wymagał dłubania kodu.

1

No tak ogólnie, to teraz raczej się pisze aplikacje warstwowe, z testowalną logiką i nie używa jakichś magicznych tableadapterów, datatable i bindowania SQL z kontrolkami GUI. To było modne 15 lat temu.
Musisz koniecznie trzymać się tych rozwiązań, czy możesz przejść na normalny podział na warstwy i użyć jakiegoś ORM do obsługi bazy?

0

Dopiero co poznaję środowisko z VS i chcę dokończyć pewien testowy projekt.
Nie muszę się koniecznie trzymać tych rozwiązań o których piszę wyżej, jednak szkoda mi teraz wszystkiego przerabiać skoro mam projekt na ukończeniu.

Uważam, że jeśli funkcjonalność jest, chciałbym poznać jak działa i ewentualnie z niej skorzystać. Chciałbym przy okazji poznać wydajność takiego rozwiązania opartego na tableadapterach.

0

To co dotychczas zrobiłem, działa, brakuje mi tylko możliwości dodawania danych do grida..

Rozumiem że datagridview i inne czarodziejskie rzeczy z nim związane są już za stare abym uzyskał jakąś podpowiedź?? :)

1

Otwórz Dataset-a w designerze, we właściwościach TableAdaptera masz (puste) pozycje UpdateCommand, InsertCommand, DeleteCommand.
Jeśli masz wątpliwości jakie instrukcje SQL-a tam wpisać to zrób fikcyjny datatable/tableadapter z jednej tabeli, zobaczysz jak robi to designer VS.

Jeśli chcesz sprawdzać poprawność danych to jako CommandType wybierz StoredProcedure, wartości do wpisania i ewentualne inne potrzebne do walidacji przekaż jako parametery.
Procedurę musisz oczywiście napisać sam. Najpierw przed instrukcją Insert/Update/Delete sprawdzisz dane, jeśli będą błędne to wywołasz wyjątek poprzez Raiserror lub Throw.
Insert/Update możesz załatwić jedną procedurą (id < 0 - insert, > 0 - update)

Procedura nie musi być zdefiniowana we właściwościach TableAdapter.Update, Insert...
Możesz ją wołać "ręcznie" z kodu. Obsługujesz zdarzenie końca edycji (RowValidating?) i wywołujesz ją (+dataTable.AcceptChanges)
Inny sposób to button Zapisz zmiany.

0
wojo1984 napisał(a):

Rozumiem że datagridview i inne czarodziejskie rzeczy z nim związane są już za stare abym uzyskał jakąś podpowiedź?? :)

DGV jest w porządku, problem jest z tableadapterami. Ja np. nie pamiętam jak ich się używa, więc nie sądzę, żebym mógł dać odpowiedź lepszą niż odesłanie do jakiegoś tutoriala.

0
niemand napisał(a):

Otwórz Dataset-a w designerze, we właściwościach TableAdaptera masz (puste) pozycje UpdateCommand, InsertCommand, DeleteCommand.
Jeśli masz wątpliwości jakie instrukcje SQL-a tam wpisać to zrób fikcyjny datatable/tableadapter z jednej tabeli, zobaczysz jak robi to designer VS.

Jeśli chcesz sprawdzać poprawność danych to jako CommandType wybierz StoredProcedure, wartości do wpisania i ewentualne inne potrzebne do walidacji przekaż jako parametery.
Procedurę musisz oczywiście napisać sam. Najpierw przed instrukcją Insert/Update/Delete sprawdzisz dane, jeśli będą błędne to wywołasz wyjątek poprzez Raiserror lub Throw.
Insert/Update możesz załatwić jedną procedurą (id < 0 - insert, > 0 - update)

Procedura nie musi być zdefiniowana we właściwościach TableAdapter.Update, Insert...
Możesz ją wołać "ręcznie" z kodu. Obsługujesz zdarzenie końca edycji (RowValidating?) i wywołujesz ją (+dataTable.AcceptChanges)
Inny sposób to button Zapisz zmiany.

Dzięki. O to mi chodziło. Czyli większość klepię ręcznie :)

W miedzyczasie poradziłem sobie zmieniając SQL w tableadapter tak aby był oparty o jedną tabelę a brakujące kolumny z innych tabel pociągnąłem podselectami. Jest to nieoptymalne jednak na potrzeby tego projektu nie ma to znaczenia. Działa wyśmienicie :)

0

a nie lepiej zrobić sobie listę, np tak.

    public class User
    {
        public string Name { get; set; }
        public string SureName { get; set; }
    }
public partial class Form1 {
 BindingList<User> users = new BindingList<User> { new User { Name = "Jan", SureName = "Kowalski" }, new User {  Name = "Tadeusz", SureName = "Nowak" } };

        private void Form1_Load(object sender, EventArgs e) => dataGridView1.DataSource = users;

        private void button3_Click(object sender, EventArgs e)
        {
           var user = new User() {Name = textBox1.Text, SureName = textBox2.Text}; 
            users.Add(user);
        }

 private void button2_Click(object sender, EventArgs e)
        {
            var data = dataGridView1.CurrentCell.Value.ToString();
            var user = users.FirstOrDefault(d => d.SureName == data);
            if (user != null)
                users.Remove(user);
        }
}
0

Nie wiedziałem że tak się da. :)
Jednak tutaj zmieniamy datasource "dataGridView1.DataSource = users" i czy to nie powoduje że tracę możliwość odczytu grida danymi z bazy poprzez dataset?

Może nakreślę ogólny wygląd forma i zasadę działania.
Po lewej mamy grida1 z listą zestawów, po prawej mamy grida2 z listą elementów aktualnie wybranego zestawu (zdjęcie, nazwa, kolor, liczba itp). Odczyt wszystkiego leci z bazy.
Pod gridem2 mamy kontrolki i przycisk za pomocą którego chcę aby dane z kontrolek dodały się do grida2.
Użyłem kontrolek ponieważ wszystkie są słownikowe (element wraz z podglądem zdjęcia elementu w pictrurebox, kolor, dostępna ilość podpowiadają się w miarę wpisywania).

Co prawda już sobie poradziłem ale chętnie poznam alternatywne rozwiązania :)

0

ale w drugą stronę też przecież możesz sobie odczytać.

var lista = dataGridView1.DataSource as BindingList<User>;

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