Just nu i M3-nätverket
Gå till innehåll

Hur lyfter jag ut min databasuppkoppling till annan klass? Data Access Layer?


Martin79

Rekommendera Poster

Just nu har jag ett Windows form där jag kopplar upp till databasen med:

 

namespace WindowsFormsApplication1
{
   public partial class InvoiceGUI : Form
   {
       System.Data.SqlClient.SqlConnection con;
       System.Data.SqlClient.SqlDataAdapter da;
       DataSet ds1;
       DataRow dRow;

       int MaxRows = 0;
       int inc = 0;

       public InvoiceGUI()
       {
           InitializeComponent();
       }

       private void Form1_Load(object sender, EventArgs e)
       {
          con = new System.Data.SqlClient.SqlConnection();
          ds1 = new DataSet();

          con.ConnectionString = "Data Source=(local);Initial Catalog=invoice_db;Integrated Security=SSPI";


           con.Open();
           //MessageBox.Show("open");

           string sql = "select * from invoice";
           da = new System.Data.SqlClient.SqlDataAdapter(sql, con);

           da.Fill(ds1, "Invoice");
           NavigateInvoice();

           //Set the max rows
           MaxRows = ds1.Tables["Invoice"].Rows.Count;

           con.Close();
           //MessageBox.Show("closed");

       }

 

Problemet är om jag har en till form och vill komma åt databasen. Hört något om Data Access Layer men en sökning gör min inte klokare. Hur lyfter jag ut kopplingen till en annan klass så att jag kan komma åt den från en annan klass (ett annat Windows form)?

 

Något enkelt exempel? Eller modifiera min kod?

Länk till kommentar
Dela på andra webbplatser

Ett data access layer i sin enklaste form är en egen klass som sköter kommunikationen till databasen.

 

Så det du behöver göra är att skapa en ny klass där du har metoder för att hämta och skicka data. Och dessa metoder i sin tur ser till att anslutningen mot databasen öppnas och stängs vid behov. Plus att du även får bra möjligheter till att logga eventuella fel.

 

Så i din kod så kan du nog börja med att klippa och klistra in koden i egen klass. Och sen anropa de nya metoderna du skapar.

Länk till kommentar
Dela på andra webbplatser

Förutom det .M just föreslagit så rekommenderar jag även att du jobbar objektorienterat och från datalagret inte returnerar databas-strukturer (såsom DataSet eller DataTable), utan hellre objektifierar datan. I ditt fall skulle du då skapa en Invoice-klass och från datalagret returnera ex. en List<Invoice> eller dylikt.

Länk till kommentar
Dela på andra webbplatser

Får inte rätt på det. Provade att bara lyfta ut själva con till en anna klass.

 

   class ConnectDB
   {
       SqlConnection con;

       public void db() {
           con = new System.Data.SqlClient.SqlConnection();
           con.ConnectionString = "Data Source=(local);Initial Catalog=invoice_db;Integrated Security=SSPI";

 

och anropar den sedan från min form load med:

 

  ConnectDB mydb = new ConnectDB();
           mydb.db();

 

Vilket inte fungerar. Någon som skulle vilja ge lite kodexempel, iaf hur jag lyfter ut uppkopplingen så förstår jag nog resten.

 

Ett data access layer i sin enklaste form är en egen klass som sköter kommunikationen till databasen.

 

Så det du behöver göra är att skapa en ny klass där du har metoder för att hämta och skicka data. Och dessa metoder i sin tur ser till att anslutningen mot databasen öppnas och stängs vid behov. Plus att du även får bra möjligheter till att logga eventuella fel.

 

Så i din kod så kan du nog börja med att klippa och klistra in koden i egen klass. Och sen anropa de nya metoderna du skapar.

Länk till kommentar
Dela på andra webbplatser

Prova något liknande det här.

class ConnectDB
{
SqlConnection con;

void Open()
{
	con = new System.Data.SqlClient.SqlConnection();
	// Connection string borde skrivas i App.config och inte hårdkodas
           	con.ConnectionString = "Data Source=(local);Initial Catalog=invoice_db;Integrated Security=SSPI";
	con.Open();
}

void Close()
{
	if(con.State != ConnectionState.Closed)
		con.Close();
}

public DataSet GetInvoices()
{
	Open();
	DataSet ds1 = new DataSet();
	string sql = "select * from invoice";
           	DataAdapter da = new System.Data.SqlClient.SqlDataAdapter(sql, con);

           	da.Fill(ds1, "Invoice");
	Close();
	return ds1;
}
}

 

Dock måste det påpekas att detta är ett exempel med hur det kan lösas. Inte hur det borde lösas.

Länk till kommentar
Dela på andra webbplatser

Glöm inte att göra klassen Public om den ligger i ett eget projekt/binär. Och snälla, slopa Datasets och Dataadapter, det är sååå Net1.1 =)

Länk till kommentar
Dela på andra webbplatser

Glöm inte att göra klassen Public om den ligger i ett eget projekt/binär. Och snälla, slopa Datasets och Dataadapter, det är sååå Net1.1 =)

 

Förslag på bättre är alltid bra när något kritiseras ;)

Länk till kommentar
Dela på andra webbplatser

Ok. Here we go, ett förslag på att skapa ett datalager som använder sig av LINQ istället.

 

Först måste du skapa en "LINQ-to-SQL-classes". Detta gör du via Add->New Item och väljer detta ur Data-sektionen. Därefter skapar du en koppling till din databas och släpar ut de tabeller du har i designer-ytan. Läs här för en steg-för-steg-beskrivning av detta: http://www.mssqltips.com/sqlservertip/1534/querying-sql-server-databases-using-linq-to-sql/

 

I mitt testexempel har jag en tabell som heter Invoice. Visual Studio har nu skapat en Invoice-klass i steget ovan, och har dessutom skapat en InvoiceDataContext som representerar din databas och alla dess tabeller. För att hämta alla poster i Invoice-tabellen använder du följande LINQ-kod:

 

InvoiceDataContext idc = new InvoiceDataContext();
var invoices = from i in idc.Invoices select i;

 

En början på ditt datalager skulle kunna se ut så här:

    public static class DataFactory
   {
       public static List<Invoice> GetInvoices()
       {
           InvoiceDataContext idc = new InvoiceDataContext();
           var invoices = from i in idc.Invoices select i;
           return invoices.ToList<Invoice>();
       }
       public static Invoice GetInvoiceByName(string name)
       {
           InvoiceDataContext idc = new InvoiceDataContext();
           var invoices = from i in idc.Invoices where i.Name==name select i;
           return invoices.First<Invoice>();
       }
   }

 

Från din övriga kod anropar du det så här:

        private void Form1_Load(object sender, EventArgs e)
       {
           MessageBox.Show(DataFactory.GetInvoiceByName("EttNamnPåFaktura").Name);
           List<Invoice> invoices = DataFactory.GetInvoices();
           invoices.ForEach(delegate(Invoice inv)
           {
               MessageBox.Show(inv.Id + " " + inv.Name);
           });


       }

 

Som du ser så har du nu en objektorienterad modell av din databas och använder sedan LINQ för att ställa SQL-liknande frågor mot databasen.

Länk till kommentar
Dela på andra webbplatser

Arkiverat

Det här ämnet är nu arkiverat och är stängt för ytterligare svar.

×
×
  • Skapa nytt...