połączenie z bazą .sdf w C#

0

Witam serdecznie i proszę o pomoc.

Piszę aplikację okienkową w C# (Visual C# 2010 Express) napisałem fukcję własną (w pliku Program.cs) pod funkcją main(). Jedynym zadaniem mojej funkcji jest pobrać z dane z tabeli bazy danych, aby później do wyników tego wyszukania odwołać się w innyej funkcji. Kod wygląda tak:

 
using System;
....

namespace AAA
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]

        double o_c(string opis); // deklaracja mojej funcji
        static void Main()
        {
            "(...)"
        }
        double o_c(string opis)
        {
            SqlCeConnection ocena = new SqlCeConnection("(...).sdf");
            ocena.Open();

            string o_o = opis;
            SqlCeDataAdapter DA_oc = new SqlCeDataAdapter("SELECT (...)", ocena);
            DataSet d_o = new DataSet();
            d_o.Tables.Add("w_s");
            DA_oc.Fill(d_o, "w_s");

            foreach (DataRow r_o in d_o.Tables[0].Rows)
            {
                string op_o = r_o["w_s"].ToString();
                double o_oc = Convert.ToDouble(op_o);

                return o_oc;
            }

            ocena.Close();
        }
    }

Proszę o pomoc gdzie popełniam błąd, że Visuala C# zgłasza następujący błąd "not all code paths return a value". Z góry dziękuję za wszystkie podpowiedzi i sugestie dla owicjusza jakim jestem.

Pozdrawiam

0

Przecież kompilator jasno Ci mówi, że nie zawsze zwracasz wartość z funkcji. Co będzie, jeżeli d_o.Tables[0].Rows będzie puste, czyli pętla się nie wykona? Jaką wartość zwróci funkcja?

0

return jest w ogóle w złym miejscu, bo wewnątrz pętli.

0

Błąd bierze się stąd, że jeśli pętla foreach nie wykona się ani razu, to ani razu nie zostanie wywołany return, a tak być przecież nie może - metoda (nie void) zawsze musi coś zwrócić.

Skoro foreach wykonuje się tylko raz, to równie dobrze mogłoby go nie być.
Metoda o_c (BTW, nazewnictwo jest w tym kodzie genialne) zwraca double. Dedukuję, że z bazy też jest pobierana pojedyncza wartość. Może zatem zamiast używać DataAdapterów i DataSetów lepiej byłoby użyć zwykłego SqlCommand i metody ExecuteScalar?

0

Witam ponownie,

idąc tropem waszych podpowiedzi kombinuję tak:

 
using System;
// (...)
namespace AAA
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]

        double o_c(string opis);
        static void Main()
        {
            // (...)
        }
        double o_c(string opis)
        {
            SqlCeConnection oc = new SqlCeConnection("(...).sdf");
            oc.Open();

            string op_o = opis;
            SqlCeDataAdapter DA_oc = new SqlCeDataAdapter("SELECT (...) WHERE aaa ='" + opis_oceny + "'", oc);
            DataSet ds_oc = new DataSet();
            ds_oc.Tables.Add("w_s");
            DA_oc.Fill(ds_oc, "w_s");
            // policzyć liczbę wierszy w wynikowej tabeli "w_s"
            int liczba_wierszy = ds_oc.Tables["w_s"].Rows.Count;
            
            if (liczba_wierszy != 0)
            {
            foreach (DataRow row_ocena in dataset_ocena.Tables[0].Rows)
                {
                string op_oceny = row_ocena["wartość_stopnia"].ToString();
                double o_oceny = Convert.ToDouble(op_oceny);
                return o_oceny;
                }
            }
            else
            {
            double o_oceny = 0;
            return o_oceny;
            }
                        
            oc.Close();
        }
    }
}

Wiem, że robię błąd ale problem w tym, że nie wiem gdzie? Proszę wskarzcie mi te błędy. Z góry dziękuję.

0

Pozwolę sobie zacytować siebie:
Co będzie, jeżeli d_o.Tables[0].Rows będzie puste, czyli pętla się nie wykona?
Masz powiedzieć kompilatorowi jasno, co wtedy funkcja ma zwrócić.

0

Witam,

Oto co wykombinowałem do tej pory:

 

using System;
// (...)
namespace AAA
{
    static class Program
    {
        double o_c(string opis); //Error	1: 'ocena_cechy': cannot declare instance members in a static class	
        [STAThread]
        static void Main()
        {
            // (...)
        }
        double o_c(string opis) //Error 2: Type 'AAA.Program' already defines a member called 'ocena_cechy' with the same parameter types; Error 3: 'o_c': cannot declare instance members in a static class


        {
            SqlCeConnection ocena = new SqlCeConnection("(...).sdf");
            ocena.Open();

            string op_o = opis;
            SqlCeDataAdapter DA_ocena = new SqlCeDataAdapter("SELECT (...) WHERE opis_st ='" + opis_oceny + "', ocena);
            DataTable datatable_oc = new DataTable();
            DA_ocena.Fill(datatable_oc);
            
            if (datatable_oc.Rows.Count == 0)
            {
                double o_oceny = 0;
                return o_oceny;
            }
            else
            {
                string op_oceny = datatable_oc.Rows.ToString();
                double o_oceny = Convert.ToDouble(op_oceny);
                return o_oceny;
            }            
        }
    }
}

W kod wpisałem również również komunikaty, które wyrzuca Visual C# 2010 Express. Z góry dziękuję za podpowiedzieć co z nimi zrobić?

Pozdrawiam

1

Umiesz czytać? Wiesz, co po polsku oznacza "cannot declare instance members in a static class" ?

0

Ok doczytałem o "cannot ...". Może dostanę jakąś wskazówkę gdzie doczytać, lub jak się pozbyć Error: Type 'AAA.Program' already defines a member called ' ' with the same parameter types.

Z góry dziękuję.

Pozdrawiam

0
zxcvbnm1 napisał(a)

Ok doczytałem o "cannot ...". Może dostanę jakąś wskazówkę gdzie doczytać, lub jak się pozbyć Error: Type 'AAA.Program' already defines a member called ' ' with the same parameter types.

Z góry dziękuję.

Pozdrawiam

dwa razy napisałeś funkcję o tej samej nazwie i tych samych parametrach

w C# nie ma czegoś takiego jak "deklaracja funkcji" (forward declaration) i nie jest potrzebna bo kolejność implementacji funkcji jest bez znaczenia

0

Ok, usunołem deklaracje funkcji z Program.cs ale pojawił się kolejny błąd (nadmienię, że idąc tym tropem usunołem również deklarację funkcji z pliku samoocena (jedno z okienek mojej aplikacji), w którym odwołuje się do wyników tej funkcji:

 
double o_cechy_01 = o_c(opis_01); // podstawiam wynik funkcji 

Problem polega na tym, że kompilator woła "Error 1: The name 'o_c' does not exist in the current context"

Co robić?

Z góry dziękuję za odpowiedź.

Pozdrawiam.

0

pokaż jaki masz teraz kod

0

W pliku samoocena.cs mam co następuje:

 
using System;
// (...) 

namespace AAA
{
    public partial class samoocena : Form
    {
        // static double ocena_cechy(string opis)
        public samoocena(string oceniający)
        {
            InitializeComponent();
            label2.Text = oceniający;

            SqlCeConnection logowanie = new SqlCeConnection("(...).sdf");

            // pobieram informacje z innej tabeli, aż dochodzę do momentu gdy potrzebuję wyniku metody o_c

foreach (DataRow row_cecha_01 in dataset_cecha.Tables[0].Rows)
{
string cecha_01 = label_samoocena_01.Text;
string ocena_cechy_01 = comboBox_samoocena_01.Text;
string opis_01 = ocena_cechy_01;
double o_cechy_01 = ocena_cechy(opis_01); //tu próbuje podstawiać
string waga_cechy_01 = dataset_cecha.Tables[0].Rows[0][0].ToString();
double w_cechy_01 = Convert.ToDouble(waga_cechy_01);
double wo_cechy_01 = o_cechy_01 * w_cechy_01;
(...)                                                                                         

sama metoda o_c się nie zmieniła mapomknę, że planuję tą metodę wykorzystać jeszcze do trzech cech.

Z góry dziękuję za podpowiedź.

Pozdrawiam

0

o_c jest metodą klasy Program. Jeśli chcesz jej użyć w klasie innej niż Program, a jak widać próbujesz to zrobić w klasie samoocena, to musisz jej nadać modyfikator dostępu public, żeby była widziana poza swoją klasą.

Jeszcze taka uwaga - w konstruktorze klasy NIGDY nie łącz się z bazą, nie rób żadnych czasochłonnych operacji ani nie korzystaj z żadnych zasobów zewnętrznych (pliki, bazy, itp.). Konstruktor to metoda, która powinna się zawsze bezbłędnie wykonać i zwrócić obiekt.

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