Permalänk
Medlem

SQL databashantering

Hej alla clockers! Sitter och håller på med en ny kurs där vi skall lära oss hantera databaser, specifikt microsofts egna program SQL server management. Har förstått grunderna i hur man ritar en databas samt skapar tables osv. Men är inte riktigt med på helheten hur man kan koppla SQL basen till Visual Studio osv. Har självklart googlat och youtubat där jag sett en del videos i hur man connectar till databas via visual studio.
Innan har vi programmerat i VS rakt av, gjort program där vi skapat olika program, så som en parkeringsplats där vi skulle skriva till fil osv. Dock förstår jag inte riktigt hur jag kan skapa ett liknande program som parkeringsplatsen och på så sätt få all data skriven till databasen istället.
För att summera det kort, parkeringsplatsprogrammet ser ut såhär:

Welcome to the menu ------------------------ 1. Add vehicle 2. Move vehicle 3. Check out a vehicle 4. Search for a vehicle 5. Show an overview of the parkinglot 6. Exit program //Sedan all kod för själva programmet i olika klasser osv

Läser om texten och inser att det kanske är lite halvflummigt skrivet, men jag undrar väl egentligen:
- Kan jag ansluta till databasen genom att skapa en sträng som söker sig till databasen på något vänster?
- Koden för programmet, kan jag skriva det i VS och i slutet för varje aktion, som exempelvis när man skriver till en fil, ha någon kod för att skicka datan till databasen?

Är det oklart vad jag menar så är det bara att fråga på mer specifikt om ni tänker på något annat, annars tar jag gärna emot tips samt om ni har någon bra sida att tipsa om.

Permalänk
Medlem

Man kan göra på många sätt. Idag används ofta en ORM (Object Relational Mapping) för att liksom sköta databasen åt en. MS har exempelvis Entity Framework. Alternativt så kan man hantera det själv mer eller mindre manuellt.

Eftersom det är utbildning och du inte nämner ORM eller EF så antar jag att läraren vill att ni hanterar det själva.

En basgenomgång: http://csharp.net-informations.com/data-providers/csharp-sql-...
Lite djupare och mer detaljerat: https://www.guru99.com/c-sharp-access-database.html

Permalänk
Medlem

Först bestämmer du dig om du ska använda det gamla ADO.NET-ramverket eller om du ska använda Entity Framework. I ADO.NET skriver man SQL själv, medan man i EF jobbar mot objekt med LINQ. I EF har man ett DbContext-objekt som har en metod som heter SaveChanges() som används för att spara ändringarna till databasen när man har manipulerat klart sina objekt. Om du redan har skapat din databas så ska du använda "database first"-varianten av EF, vilket innebär att du måste generera upp kod som avspeglar databasen från databasen genom Visual Studio. Troligen vill läraren att ni ska använda ADO.NET.

I bägge fallen behöver du en connectionString som talar om hur programmet ska koppla upp sig mot databasen. Konfiguration i app.config för det ser ut i stil med:

<add name="MinDatabas" providerName="System.Data.SqlClient" connectionString="Server=.;Database=MinDatabas;Trusted_Connection=True;" />

Ovanstående använder Windows Authentication för inloggningen i databasen, dvs du loggar in genom att vara inloggad i Windows, konton som satts upp i SQL Server funkar inte för det här exemplet. Punkten efter Server betyder att du kopplar upp mot din lokala maskin.

Permalänk
Medlem
Skrivet av KAD:

Först bestämmer du dig om du ska använda det gamla ADO.NET-ramverket eller om du ska använda Entity Framework. I ADO.NET skriver man SQL själv, medan man i EF jobbar mot objekt med LINQ. I EF har man ett DbContext-objekt som har en metod som heter SaveChanges() som används för att spara ändringarna till databasen när man har manipulerat klart sina objekt. Om du redan har skapat din databas så ska du använda "database first"-varianten av EF, vilket innebär att du måste generera upp kod som avspeglar databasen från databasen genom Visual Studio. Troligen vill läraren att ni ska använda ADO.NET.

I bägge fallen behöver du en connectionString som talar om hur programmet ska koppla upp sig mot databasen. Konfiguration i app.config för det ser ut i stil med:

<add name="MinDatabas" providerName="System.Data.SqlClient" connectionString="Server=.;Database=MinDatabas;Trusted_Connection=True;" />

Ovanstående använder Windows Authentication för inloggningen i databasen, dvs du loggar in genom att vara inloggad i Windows, konton som satts upp i SQL Server funkar inte för det här exemplet. Punkten efter Server betyder att du kopplar upp mot din lokala maskin.

Okejokej då är jag med på hur jag skall starta iallafall, tänkte att jag tar kvällen här nu och testar lite och ser hur långt jag kommer! Återkommer med en uppdatering imorgon! Tack för svar

Permalänk
Medlem

Okej har googlat runt lite samt kollat videos, blev mycket enklare efter jag visste vad jag skulle söka efter. Min start är nu detta:
Började med att öppna upp SQL server management, connectade till databasen. Sedan in på VS, skapade ett nytt projekt. Därifrån gick jag in på appconfig,
Skapade en Connectionstring

<connectionStrings> <add name ="connectToDataBase" connectionString="anslutningssträngen" providerName="System.Data.SqlClient"/> </connectionStrings>

Efter detta, in i main, skapade en sträng som antagligen innehåller anslutningen(?), sedan ett sql objekt som håller i anslutningen.
Öppnar sedan anslutningen, kod och stänger anslutningen.

string connString; connString = ConfigurationManager.ConnectionStrings["connectToDataBase"].ConnectionString; //connString som håller kopplingen från App.Config(?) SqlConnection sqlConnection = new SqlConnection(connString); sqlConnection.Open(); //Öppna anslutning före användning //Kod sqlConnection.Close(); //Stäng anslutning efter användning

Är jag på rätt väg?

Permalänk
Medlem

Tja igen! Har lyckats att connecta till min databas nu, gjort några tables osv samt skapat ett simple program där användaren får ange sina uppgifter och så lagras detta i databasen vilket var tanken. Tack för hjälpen såhär långt!

Det jag undrar nu är, och ska försöka förklara så bra jag kan är:

Mitt program är konsolbaserat, jag har skapat några klasser osv och gjort så att användare får mata in sina uppgifter och så sparas detta till databasen. Det jag har gjort i databasen är att endast skapat några tables. Har sett ett exempel där en person gör det mesta av kodandet i SQL, såhär ser det ut för att tydliggöra:

Exempel jag har sett:

Vehicle addedVehicle = new Vehicle(); SqlCommand sqlCommand = new SqlCommand(); SqlConnection sqlConnection = new SqlConnection(SQLDataSource.ConnectionString); sqlCommand.Connection = sqlConnection; sqlCommand.CommandText = "dbo.USP_AddVehicle"; sqlCommand.CommandType = CommandType.StoredProcedure; addedVehicle.registrationNumber = UserInputs.GetVehicleRegistrationNumber(); Console.Clear(); addedVehicle.vehicleTypeID = UserInputs.GetVehicleType(); Console.Clear(); sqlCommand.Parameters.AddWithValue("@RegistrationNumber", addedVehicle.registrationNumber); sqlCommand.Parameters.AddWithValue("@VehicleType", addedVehicle.vehicleTypeID); var returnParameter = sqlCommand.Parameters.Add("@FirstParkingSpace", SqlDbType.Int); returnParameter.Direction = ParameterDirection.ReturnValue; int result = 0; try { using (sqlCommand.Connection) { sqlCommand.Connection.Open(); int resultAddVehicle = sqlCommand.ExecuteNonQuery(); if (resultAddVehicle > 0) { Console.WriteLine("The vehicle has been sucessfully added"); result = (int)returnParameter.Value; } else { Console.WriteLine("The new vehicle has not been added due to an unforseen event"); } } } catch { Console.WriteLine("Something went wrong when trying to add a new vehicle. Please try again, if problem persists contact software suppport."); sqlCommand.Connection.Close(); } return result;

Medan min kod, han gör om fordon och jag personer, men tänker att tanken är väl någorlunda densamma:

Console.Clear(); string connString; connString = ConfigurationManager.ConnectionStrings["connectToDataBase"].ConnectionString; SqlConnection sqlConnection = new SqlConnection(connString); sqlConnection.Open(); string firstName, lastName, gender; int birth; Console.Write("Enter your firstname: "); firstName = Console.ReadLine(); Console.Clear(); Console.Write("Enter your lastname: "); lastName = Console.ReadLine(); Console.Clear(); Console.Write("Enter your gender: "); gender = Console.ReadLine(); Console.Clear(); Console.Write("Enter your birth: "); birth = int.Parse(Console.ReadLine()); SqlCommand cmd = new SqlCommand("INSERT INTO Person VALUES('" + firstName + "', '" + lastName + "', '" + gender + "', '" + birth + "')", sqlConnection); int i = cmd.ExecuteNonQuery(); if (i > 0) { Console.Clear(); Console.WriteLine("Insertion successfull!\n\n"); Console.Write("Press any key to return to the menu. . ."); Console.ReadKey(); } else { Console.Clear(); Console.WriteLine("Someting went wrong!\n\n"); Console.Write("Press any key to return to the menu. . ."); Console.ReadKey(); } sqlConnection.Close();

Jag gissar väl på att han skriver sina funktioner i SQL, kan man göra på båda sätten eller finns det ett rätt sätt?

Permalänk
Medlem

Båda varianterna är tänkbara. Din inspirationskälla har skapat stored procedures i SQL server och anropar dem.

Det man definitivt ska försöka undvika är att konkatenera strängar från något som användaren kan styra över till SQL, så som du gör nu. Det är ett recept för ”SQL injection”-attacker. Använd ”parameterized queries” om du vill hantera SQL-koden tillsammans med C#-koden.

I allmänhet finns det nog en del prestanda att vinna med stored procedures, men i ditt program kommer det inte spela någon roll.

Du kan vilja titta på databasprojekt i Visual Studio, där kan man hantera databasschemat, stored procedures med mera från Visual Studio.

Permalänk
Medlem

Ett alternativ är att koppla ett recordset mot en tabell i databasen och göra inserts på recordset.
https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/re...

Edit, sorry, det är DataTable som är objektet du kan skriva mot.

Permalänk
Medlem
Skrivet av KAD:

Båda varianterna är tänkbara. Din inspirationskälla har skapat stored procedures i SQL server och anropar dem.

Det man definitivt ska försöka undvika är att konkatenera strängar från något som användaren kan styra över till SQL, så som du gör nu. Det är ett recept för ”SQL injection”-attacker. Använd ”parameterized queries” om du vill hantera SQL-koden tillsammans med C#-koden.

I allmänhet finns det nog en del prestanda att vinna med stored procedures, men i ditt program kommer det inte spela någon roll.

Du kan vilja titta på databasprojekt i Visual Studio, där kan man hantera databasschemat, stored procedures med mera från Visual Studio.

Jasåå, ja nu när jag fick ett namn på det så blev googlingen 1000 gånger lättare ser jag direkt, dyker upp en massa saker att kolla på, det spanar jag in, tack för det!

Okej den är jag med på, blir en post it på skärmen som påminner mig att skriva på det sättet istället, bra tips!

Då har jag lite att göra igen, satt fast innan då jag inte hittade några bra svar på mina googlingar men nu dök det ju upp massor

Permalänk
Medlem
Skrivet av Mordekai:

Ett alternativ är att koppla ett recordset mot en tabell i databasen och göra inserts på recordset.
https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/re...

Skall läsa på om det! Tack för tips

Permalänk
Medlem
Skrivet av PapaDiouf:

Jasåå, ja nu när jag fick ett namn på det så blev googlingen 1000 gånger lättare ser jag direkt, dyker upp en massa saker att kolla på, det spanar jag in, tack för det!

Okej den är jag med på, blir en post it på skärmen som påminner mig att skriva på det sättet istället, bra tips!

Då har jag lite att göra igen, satt fast innan då jag inte hittade några bra svar på mina googlingar men nu dök det ju upp massor

Man kan absolut göra det mesta i databasen, men det är inte riktigt så man jobbar idag utan tvärtom försöker man abstrahera bort databasen så mycket som möjligt. På mitt förra jobb jobbade jag med en produkt som var äldre, typ från 2001 från början, där väldigt mycket logik låg i databasen och det funkade och var snabbt för många saker, men det var ju ett helvete att underhålla, lätt att göra fel och debugging och liknande lämnade ju mycket att önska. Idag kör man ju EF eller liknande och försöker undvika att tänka på databasen alls, vilket funkar bra så länge man inte gör väldigt datatunga saker, då saknar man de SQL-experter som man sa upp tidigare.

Permalänk
Medlem
Skrivet av snajk:

Man kan absolut göra det mesta i databasen, men det är inte riktigt så man jobbar idag utan tvärtom försöker man abstrahera bort databasen så mycket som möjligt. På mitt förra jobb jobbade jag med en produkt som var äldre, typ från 2001 från början, där väldigt mycket logik låg i databasen och det funkade och var snabbt för många saker, men det var ju ett helvete att underhålla, lätt att göra fel och debugging och liknande lämnade ju mycket att önska. Idag kör man ju EF eller liknande och försöker undvika att tänka på databasen alls, vilket funkar bra så länge man inte gör väldigt datatunga saker, då saknar man de SQL-experter som man sa upp tidigare.

Jahaa okej! Så överlag försöker man göra det mesta från visual studio då? Eller, man kan ju skapa tables o stored procedures där med men menar att man sköter dom flesta funktionerna från visual studio och inte sitter och skriver funktioner i sql?

Permalänk
Medlem
Skrivet av PapaDiouf:

Jahaa okej! Så överlag försöker man göra det mesta från visual studio då? Eller, man kan ju skapa tables o stored procedures där med men menar att man sköter dom flesta funktionerna från visual studio och inte sitter och skriver funktioner i sql?

Nja, man gör sakerna i kod och använder bara databasen till att lagra saker. Helst utan att ens fundera på hur databasen ska se ut och fungera.

Säg att du har ett program som det klassiska bibliotekssystemet som ofta används som skoluppgift. Alltså hantera böcker, lån och användare. Säg att du vill ha en funktion som skickar ut en påminnelse till alla som har lån som är på väg att gå ut.

Det klassiska sättet hade varit att skapa ett schemalagt jobb i databasen som körde ett antal stored procedures i ordning för att hitta dessa personer, plocka ut information om lånet och övrigt som behövs i påminnelsen varje morgon eller så, allt helt i databasen. Själva utskickandet av påminnelsen kan man förstås lösa på diverse sätt, beroende på vad man har för tjänster tillgängliga, dbmail finns exempelvis men det är inte direkt byggt för den typen av utskick utan mer för att larma en person om något går fel eller liknande. Så antagligen hade man gjort det utanför databasen även tidigare, alternativt hade man haft ett annat databasjobb som tog allt som behövs för utskicken från en tabell (skapad av föregående jobb) och skickade över dem till någon mail-leverantör.

Idag hade man sannolikt gjort det med schemalagda programkörningar istället. Resultatet blir det samma i slutändan även om prestandan inte når upp till rena databasoperationer, men det spelar ofta mindre roll idag då datorerna är så snabba ändå. Fördelen är ju framför allt att det är lättare att underhålla och utveckla.

Säg att du behöver lägga till ny information i ditt utskick, i databasen kanske du behöver ändra både tabeller och rätt många stored procedures för att lösa det, medan man i kod (om den är strukturerad bra) bara behöver lägga till en egenskap till exempelvis bokobjektet, och förstås parsning in i meddelandetexten. Informationen hänger med i övrig logik utan att man behöver tänka på att objektet har utökats med mer information.

Å andra sidan har ju databasmotorerna fått mer funktionalitet också, så det går säkert att bolla med objekt där också idag. Men det är ju inte vad språket är byggt för så även om det går är det inte alls lika smidigt. Men behöver man göra stora batchoperationer på stora mängder data så är fortfarande databasen överlägsen. Den är ju byggd för att vara snabb och inte begränsas av minnesmängd och så, vilket inte alls gäller exempelvis C#.

Permalänk
Medlem
Skrivet av snajk:

Nja, man gör sakerna i kod och använder bara databasen till att lagra saker. Helst utan att ens fundera på hur databasen ska se ut och fungera.

Säg att du har ett program som det klassiska bibliotekssystemet som ofta används som skoluppgift. Alltså hantera böcker, lån och användare. Säg att du vill ha en funktion som skickar ut en påminnelse till alla som har lån som är på väg att gå ut.

Det klassiska sättet hade varit att skapa ett schemalagt jobb i databasen som körde ett antal stored procedures i ordning för att hitta dessa personer, plocka ut information om lånet och övrigt som behövs i påminnelsen varje morgon eller så, allt helt i databasen. Själva utskickandet av påminnelsen kan man förstås lösa på diverse sätt, beroende på vad man har för tjänster tillgängliga, dbmail finns exempelvis men det är inte direkt byggt för den typen av utskick utan mer för att larma en person om något går fel eller liknande. Så antagligen hade man gjort det utanför databasen även tidigare, alternativt hade man haft ett annat databasjobb som tog allt som behövs för utskicken från en tabell (skapad av föregående jobb) och skickade över dem till någon mail-leverantör.

Idag hade man sannolikt gjort det med schemalagda programkörningar istället. Resultatet blir det samma i slutändan även om prestandan inte når upp till rena databasoperationer, men det spelar ofta mindre roll idag då datorerna är så snabba ändå. Fördelen är ju framför allt att det är lättare att underhålla och utveckla.

Säg att du behöver lägga till ny information i ditt utskick, i databasen kanske du behöver ändra både tabeller och rätt många stored procedures för att lösa det, medan man i kod (om den är strukturerad bra) bara behöver lägga till en egenskap till exempelvis bokobjektet, och förstås parsning in i meddelandetexten. Informationen hänger med i övrig logik utan att man behöver tänka på att objektet har utökats med mer information.

Å andra sidan har ju databasmotorerna fått mer funktionalitet också, så det går säkert att bolla med objekt där också idag. Men det är ju inte vad språket är byggt för så även om det går är det inte alls lika smidigt. Men behöver man göra stora batchoperationer på stora mängder data så är fortfarande databasen överlägsen. Den är ju byggd för att vara snabb och inte begränsas av minnesmängd och så, vilket inte alls gäller exempelvis C#.

Grym info! Tack för det
Har suttit hela eftermiddagen och googlat och försökt skriva lite saker men känner att det har tagit helt stopp nu, vad gör jag för fel? Programmet hoppar över min if sats och får stort felmeddelande :'(

Min stored procedure ser ut såhär

CREATE PROCEDURE [spAddPerson] @FirstName nvarchar(30), @LastName nvarchar(30), @Gender nvarchar(6), @Birth date, @person_id int OUT AS BEGIN INSERT INTO [dbo].[Person] VALUES (@FirstName, @LastName, @Gender, @Birth) SELECT @person_id = SCOPE_IDENTITY() END

Min addmetod ser ut såhär

Console.Clear(); Person addPerson = new Person(); string connString = ConfigurationManager.ConnectionStrings["connectToDataBase"].ConnectionString; using (SqlConnection connection = new SqlConnection(connString)) { SqlCommand cmd = new SqlCommand("spAddPerson", connection); cmd.CommandType = System.Data.CommandType.StoredProcedure; addPerson.FirstName = UserInputHandler.FirstName(); addPerson.LastName = UserInputHandler.LastName(); addPerson.Gender = UserInputHandler.Gender(); addPerson.Birth = UserInputHandler.Birth(); cmd.Parameters.AddWithValue("[@Firstname]", addPerson.FirstName); cmd.Parameters.AddWithValue("[@LastName]", addPerson.LastName); cmd.Parameters.AddWithValue("[@Gender]", addPerson.Gender); cmd.Parameters.AddWithValue("[@Birth]", addPerson.Birth); SqlParameter outputParam = new SqlParameter(); outputParam.ParameterName = "@person_id"; outputParam.SqlDbType = System.Data.SqlDbType.Int; outputParam.Direction = System.Data.ParameterDirection.Output; cmd.Parameters.Add(outputParam); try { connection.Open(); int i = cmd.ExecuteNonQuery(); if(i > 0) { Console.Clear(); Console.Write("Person successfully added!"); Console.ReadKey(); } else { Console.Clear(); Console.Write("Something went wrong!"); Console.ReadKey(); } } catch(Exception msg) { Console.Clear(); Console.WriteLine(msg); Console.ReadKey(); } finally { connection.Close(); }

Syftet är att kunna lägga till en person med hjälp av användarens input, försöker debugga men ser inte felet riktigt zzZZ