webForumDet fria alternativet

Prestanda frågor

.NETur .NET

58 svar · 2 132 visningar · startad av thevice · sida 2 av 3

Frågan, av thevice

Hej! Jag har funderat lite på prestanda frågor när det gäller databas hantering och datan från databaser: 1\. Vad går snabbast, använda SqlDataSource eller skriva databaskopplingen och allt själv i codebehind? SqlDataSource är ju mycket bekvämare. Då jag använder MySQL och SqlDatasource är ju inte gjort för MySQL men det kanske inte gör någon skillnad. 2\. Känar man på att skriva ut resultaten

Läs frågan i sin helhet →
Medlem sedan maj 20012 812 inlägg
#21

nickemannen skrev:

t.ex. NHibernate scannar ju av en eller flera assemblies och det vill man ju inte göra varje gång en aspx sida anropas utan bara en gång och då läggs det lämpligtsvis i en factory.

Okej, så det hela handlar egentligen inte om någon databaskoppling, utan mer om prestandaökningar vid NHibernate och dess långsamma uppstart. Det är ju en viss skillnad... ;)

- M

// råkade trycka på fel knapp så ni undrar om jag tagit bort något från Gladh's meddelande.

Medlem sedan aug. 20003 575 inlägg
#22

Gladh skrev:

nickemannen skrev:

t.ex. NHibernate scannar ju av en eller flera assemblies och det vill man ju inte göra varje gång en aspx sida anropas utan bara en gång och då läggs det lämpligtsvis i en factory.

Okej, så det hela handlar egentligen inte om någon databaskoppling, utan mer om prestandaökningar vid NHibernate och dess långsamma uppstart. Det är ju en viss skillnad... ;)

- M

// råkade trycka på fel knapp så ni undrar om jag tagit bort något från Gladh's meddelande.

Absolut, men ett BL lager som man kan ha som Session eller liknande kan behöva läsa in annat.. tog NHibernate som ett exempel :).
Det handlade om en metod att smidigt komma åt sitt BL/Datalager.
Bara tips :)

Medlem sedan dec. 2005198 inlägg
#23

http://dev.booring.se

Märkte nu att mitt webhotell inte klarar av SqlDataSoruce. Finns det någon DLL som jag kan ladda upp för det ska fungera?
Ni kan logga in med Padchi/timmie. Jag vet inte vad det är för kod som ni vill se?

Finns det någon artikel eller liknande som förklarar det ni pratar om? För Gladhs sett värkar vara fruktansvärt bra och lätt bara man förstår det, en förklaring skulle inte sitta fel. :)

Medlem sedan maj 20012 812 inlägg
#24

thevice skrev:

Märkte nu att mitt webhotell inte klarar av SqlDataSoruce.

SqlDataSource är en internt objekt från MS, så antingen så finns det ASP.NET 2.0 (tror inte den finns med i 1.1) installerat på servern eller så har de klantat sig rejält på ditt webhotell.

Det andra alternativet är att du har en kontrollpanel där du kan välja om det är ASP.NET 1.1 eller 2.0 som din website skall använda. I IIS:en så finns den valmöjligheten och om man väljer fel version så fungerar inte siten.

thevice skrev:

För Gladhs sett värkar vara fruktansvärt bra och lätt bara man förstår det, en förklaring skulle inte sitta fel.

Vad är det du inte förstår? Koden är ju självförklarandes ;). Mitt tips till dig blir att strunta i Interfacet och basklassen till en början och fokuser på själv DataAccess klassen och luska ut hur den fungerar, ta bort basklasen och gör om alla metoder till publica och bort med override, så bör den fungera fint.

- M

Medlem sedan dec. 2005198 inlägg
#25

Jag har 2.0 på mitt webbhotell men det är jag hundra på. Så de måste ha klantat sig rejält på mitt webbhotell eller något. Ska mejla de.

Jag kan nog förstå koden och använda den om du t.x bara visar hur man gör för att hämta datan så ska jag nog luska ut hur det fungerar. Har aldrig stött på DBCommandObjekt förut så du kanske förstår att det är svårt för mig. :)

Medlem sedan maj 20012 812 inlägg
#26

IDbCommand är bara ett interface som exempelvis SqlDbCommand implementerar, så har du någongång använt SqlDbCommand (brukar man göra om man anropar StoreProcedurer, eller vill ha paramitiserade SQL frågor) så kan du skicka in det och connectionstringen till en metod och få tillbaka data som ett DataTable som du kan binda direkt till din repeater eller annan visningskontroll.

Själv så omvandlar jag DataTable till en lista av objekt så jag använder aldrig DataTablen i min kod...

- M

Medlem sedan dec. 2005198 inlägg
#27

Du har jag lyckats sabba så att SqlDatasource inte fungerar på min dator heller med MySQL. Gladh tyvärr så är allt grekiska för mg som du säger har inte så stor koll på .NET som jag trodde. Funderar på att använda detta:
http://tant102.mine.nu/project/tant102.data/details.aspx

Men vet inte om det är bra för prestandan eller om det kommer funka i längden för mitt projekt.

Medlem sedan dec. 19996 522 inlägg
#28

Har inte kollat igenom tant102s kod men hade hellre använt mig av något mer väldokumenterat och använt, som active record implementationen i castleproject, http://www.castleproject.org/activerecord/index.html

Medlem sedan jan. 20022 440 inlägg
#29

Gladh skrev:

IDbCommand är bara ett interface som exempelvis SqlDbCommand implementerar, så har du någongång använt SqlDbCommand (brukar man göra om man anropar StoreProcedurer, eller vill ha paramitiserade SQL frågor) så kan du skicka in det och connectionstringen till en metod och få tillbaka data som ett DataTable som du kan binda direkt till din repeater eller annan visningskontroll.

Själv så omvandlar jag DataTable till en lista av objekt så jag använder aldrig DataTablen i min kod...

- M

Lust att ge exempel på hur det skulle kunna se ut? Själv kör jag uteslutande på datatable och är nyfiken på alternativ och varför m,an skulel välja det.

Medlem sedan maj 20012 812 inlägg
#30

thevice skrev:

Du har jag lyckats sabba så att SqlDatasource inte fungerar på min dator heller med MySQL

Nja... jag vill nog inte ta åt mig äran att SqlDataSource inte fungerar med MySQL. SqlDataSource är en kontroll som jag inte har så mycket makt över ;) Om den inte fungera så får du nog titta igenom dina parameter på denna kontroll...

Thevice skrev:

Men vet inte om det är bra för prestandan eller om det kommer funka i längden för mitt projekt.

Det kod exemplet som du hänvisade till gav inte så mycket svar på om var bra prestandamässigt eller ej, då implemntation ligger i DatabaseObject och de kunde jag inte hitta någon kod till.

- M

Medlem sedan maj 20012 812 inlägg
#31

CatZ skrev:

Lust att ge exempel på hur det skulle kunna se ut?

Vad ni måste komplicera till saker som inte finns!!!

Här kommer ett lite kod exempel på hur man kan använda klasen. Glöm bort interfacet och basklassen utan förutsätt att du endast har en SqlServer som du alltid skall köra emot.

            IDbCommand command = new SqlCommand();
            command.CommandType = CommandType.Text;
            command.CommandText = "SELECT * FROM [Table]";

            TS.DataAccess.SqlServer.DataAccess  dataAccess = new TS.DataAccess.SqlServer.DataAccess();
            DataTable dataTable = dataAccess.ExecuteDataTableResult("MY_CONNECTION_STRING", command);

Om man däremot skulle vilja kunna ändra databaskälla på ett enkelt sätt så skall man implementerar Interfacet och använda sig av det istället.

            IDbCommand command = new SqlCommand();
            //-- Om man vill använda Access istället för SqlServer
            //IDbCommand command = new OleDbCommand();
            command.CommandType = CommandType.Text;
            command.CommandText = "SELECT * FROM [Table]";

            //-- Om man vill använda SqlServer som datakälla
            IDataAccess  dataAccess = new TS.DataAccess.SqlServer.DataAccess() as IDataAccess;
            //-- Om man vill använda Access som datakälla
            //-- IDataAccess  dataAccess = new DataAccess.Access.DataAccess() as IDataAccess;

            DataTable dataTable = dataAccess.ExecuteDataTableResult("MY_CONNECTION_STRING", command);

Givetviss lägger man valet av datakälla i en egen metod så man bara ha ett IDataAcces och opererar på, typ så här:

            IDbCommand command = new SqlCommand();
            command.CommandType = CommandType.Text;
            command.CommandText = "SELECT * FROM [Table]";

            //-- Skapa en dataAccess instanse för SqlServer
            IDataAccess  dataAccess = GetDataAccess(DataAcccesType.SqlServer);

            DataTable dataTable = dataAccess.ExecuteDataTableResult("MY_CONNECTION_STRING", command);

catz skrev:

Själv kör jag uteslutande på datatable och är nyfiken på alternativ och varför m,an skulel välja det.

Tja denna kod returnerar ju också ett DataTable så jag skulle inte tro att du vinner så mycket på att ändra till denna kod, då den säkert gör samma sak som din kod.

- M

Medlem sedan juni 20003 076 inlägg
#32

CatZ skrev:

Lust att ge exempel på hur det skulle kunna se ut? Själv kör jag uteslutande på datatable och är nyfiken på alternativ och varför m,an skulel välja det.

För risk att bli utbuad av experterna så visar jag hur jag gör. :D
(ignorera mina databasmetoder utan kolla på tillvägagångssättet bara)

public class Contents
{

    private int _ContentID;
    private string _ContentName;
    
    public int ContentID
    {
        get { return _ContentID; }
        set { _ContentID = value; }
    }

    public string ContentName
    {
        get { return _ContentName; }
        set { _ContentName = value; }
    }
}

public class ContentManager
{
    public List<Contents> GetContentByMenuID(int menuID)
    {
        DataManager dm = new DataManager();
        DataTable dt = null;
        SqlParameter[] param = { dm.AddParam("@MenuID", SqlDbType.Int, menuID) };

        dt = dm.GetTable("Content_GetContentByMenuID", CommandType.StoredProcedure, param);

        List<Contents> content = new List<Contents>();

        foreach (DataRow dr in dt.Rows)
        {
            Contents c = new Contents();
            c.ContentID = (int)dr["ContentID"];
            c.ContentName = (string)dr["ContentName"];
            content.Add(c);
        }

        return content;
    }
}

Fördelen med detta är nog himla många men en grej som är skönt är att aldrig behöva stava till kolumnerna utan man får upp namnen i intellisensen.
Ex. c.ContentID istället för (int)dr["ContentID"]
Detta gäller även om du lägger till en objectdatasource mot t.ex. en dropdownlist.
Fiffigt! :)

En fråga har jag också: (sorry thevice att vi lånar din tråd, hoppas det inte gör nått! :r )
Finns det ett enklare sätt att fylla listen direkt från databasen mot som jag gör ovan, att först skapa en datatable som sedan loopar?

Medlem sedan dec. 19996 721 inlägg
#33

doggelito skrev:

(ignorera mina databasmetoder utan kolla på tillvägagångssättet bara)

Tyckte nog att det såg rätt bra ut. Jag tänker bara ha en åsikt om att det är lite onödigt att använda en DataTable, när allt ändå sker internt i en metod. En DataReader (som ändå används för att fylla på DataTable) räcker bra. Dessutom är det kanske kontraktsmässigt knasigt att returnera en List<T>, eftersom det är en "påfyllningsbar" klass och en Add till den listan är kanske inte rimlig. Om möjligt, returnera som IEnumerable<T> (tyvärr saknar frameworket en IReadOnlyList<T>. Mycket synd.)

doggelito skrev:

Fördelen med detta är nog himla många men en grej som är skönt är att aldrig behöva stava till kolumnerna utan man får upp namnen i intellisensen.

Ja, det är skönt, men den stora fördelen är att man hårdtypar all tillgång till egenskaperna, så en eventuell felstavning el. likn. kommer inte att krypa igenom kompileringen (om man inte stavar fel när man fyller på, förstås)

doggelito skrev:

Finns det ett enklare sätt att fylla listen direkt från databasen mot som jag gör ovan, att först skapa en datatable som sedan loopar?

Visst kan man göra en generell metod för det hela, genom att använda reflection, men det är inte så mycket enklare och ur typsäkerhets- och prestandahänseende är det definitivt sämre.

Medlem sedan maj 20012 812 inlägg
#34

Doggelito skrev:

För risk att bli utbuad av experterna så visar jag hur jag gör.

Jag tycker din kod ser bra ut, du har gjort dig en väldig, väldigt enkel OR-Mapper, du tar data från databasen och mappar in i din objekt. Nu skall en OR-Mapper ha så mycket mer och vara generell, men alla resor börjar med ett litet steg...

Sedan så vet jag inte om emisson har rätt angående datareadern, jag hade hållt med honom om du inte hade använt dig av DataManager men eftersom du skapar ett objekt för att hämta data från databasen till din instans och sedan använder denna data i din kod, så måste metoden i DataManager själv ansvara för att kopplingen till databasen stängs och därför tycker jag det är bättre att returnera tillbaka en datatable istället för en datareader som kräver en öppen koppling. IMHO ;)

Angåend om det finns enklar sätt än skapa datatable och loopa igenom. Använda dig av LINQ som kommer i .NET 3.5. Om man inte har mer krav på sin OR-Mapper än att den skall kunna omvandla från databas till objekt och kunna gör SELECT/INSERT/DELETE på datan så är nog LINQ vägen att gå. Min egen ORMapper kunde ungefär det som LINQ kan, men med LINQ får jag typsäkerhet på ett helt annat sätt. Så jag skall byta till LINQ i mina projekt när jag får tid att installera VS2008...

- M

Medlem sedan dec. 19996 721 inlägg
#35

Gladh skrev:

Sedan så vet jag inte om emisson har rätt angående datareadern, jag hade hållt med honom om du inte hade använt dig av DataManager men eftersom du skapar ett objekt för att hämta data från databasen till din instans och sedan använder denna data i din kod, så måste metoden i DataManager själv ansvara för att kopplingen till databasen stängs och därför tycker jag det är bättre att returnera tillbaka en datatable istället för en datareader som kräver en öppen koppling. IMHO ;)

Jag förstår precis vad du menar, men i och med att DataManagern används på ett kontrollerat sätt och sannolikt inte skickas ut i "slarvkänsliga" lager så tycker att det kan vara värt att använda en reader.

Medlem sedan dec. 2005198 inlägg
#36

Jag har funderat lite, och vad jag egentligen söker när det gäller databashantering är något som gör livet lättare för mig. Dvs att allt går snabbare.
Skulle det inte gå att göra något liknande detta eller är jag helt ute och cyklar?
Sidan.aspx.cs:

protected void Page_Load(object sender, EventArgs e)
{
	SiteEngine.GetData("SELECT * FROM Table");
	Repeater1.DataSource = VadSkaManSkrivaHär?;
	Repeater1.DataBind();
}

SiteEngine.cs:

protected void GetData(string SqlCommand)
{
	using (MySqlConnection objConnection = new MySqlConnection("DatabasKoppling"))
	{
		objConnection.Open();
		using (MySqlCommand objCommand = new MySqlCommand(SqlCommand, objConnection))
		{
			using (MySqlDataReader objDataReader = objCommand.ExecuteReader())
			{
				if (!objDataReader.HasRows) { lblEmpty.Visible = true; }
				else
					return objDataReader;
			}
		}
		objConnection.Close();
	}
}

Ni får troligtvis ett gott skratt när ni ser koden. Men jag hoppas ni förstår vad jag vill åstakomma. Går det att göra så på ett enkelt sätt? Är det bra eller dåligt om man tänker på prestandan?

Om det går att göra på det där sättet så går det ju ganska lätt sen att binda det till en ObjectDatasource.

En annan fråga, jag har aldrig fattat vad dessa rader är bra för:
private string _Något;

public int Något
{
get { return _Något; }
set { _Något = value; }
}

Det är väll mest det som skrämmer mig, jag är allergisk mot många rader kod (kanske därför jag vill använda SqlDataSource/ObjectDatasource?) Sedan så skulle det ta himla lång tid att skriva alla mina columner för varje tabell jag har. Är det nödvändigt? Måste man göra på det sättet? Vad är det bra för?

Medlem sedan dec. 19996 721 inlägg
#37

thevice skrev:

Ni får troligtvis ett gott skratt när ni ser koden.

ROFL! ;)

thevice skrev:

Men jag hoppas ni förstår vad jag vill åstakomma. Går det att göra så på ett enkelt sätt? Är det bra eller dåligt om man tänker på prestandan?

Det går la alldeles utmärkt, men GetData bör returnera något som du kan tilldela till DataSource.

thevice skrev:

En annan fråga, jag har aldrig fattat vad dessa rader är bra för:
private string _Något;

public int Något
{
get { return _Något; }
set { _Något = value; }
}

Den koden kapslar in variabeln (field) "_Något" i en egenskap (property) som heter "Något", och ska primärt jämföras med att bara skirva:

public int Något;

För vissa är detta något av en religion, men fördelerna med att kapsla in värdet är bl.a

  • Man kan utföra värdekontroller (är värdet tillåtet) i set-metoden
  • Man kan sätta olika tillgänglighet på get och set, T.ex public get och protected set
  • Man kan kapsla in något helt annat än en enkel variabel, t.ex. egenskapen hos en annan variabel (return _någotannat.Något) eller returvärdet från en metod (return EnMetod())

Förvisso kan det tyckas vara overkill att använda detta när det ser ut som "Något"-exemplet ovan, och jag är inte så religiös när det gäller detta att jag tänker gnälla på de som inte gör så, men jag ser det som en stor fördel att klassen behåller sin utformning även när man gör förändingar. Kanske returnerar jag "_Något" i första utgåvan, men kommer sedan på att jag egentligen ville returnera "_någotannat.Något". Då är det bra att jag inte förändrar klassen mer än hur get-accessorn ser ut. En intern förändring, inget externt.

thevice skrev:

Det är väll mest det som skrämmer mig, jag är allergisk mot många rader kod (kanske därför jag vill använda SqlDataSource/ObjectDatasource?)

Ofta skriver man många rader kod på ett ställe, för att sedan kunna nöja sig med jättelite kod på många andra ställen.

thevice skrev:

Sedan så skulle det ta himla lång tid att skriva alla mina columner för varje tabell jag har.

Visst tar det en stund, men Visual Studio hjälper till. Skapa den lokala variablen, högerklicka på den, välj refactor->encapsulate field. Boom!

Som kuriosa kan jag nämna att get och set bakom kulisserna kompileras till två vanliga metoder. En int get_Något() och en void set_Något(int value).

Medlem sedan dec. 2005198 inlägg
#38

Tack för det emission.

emission skrev:

Det går la alldeles utmärkt, men GetData bör returnera något som du kan tilldela till DataSource.

Så man kanske borde gör något liknande detta: return x = objDataReader;
Eller har jag förstått helt fel? Finns det något namn på det som jagg förösker göra? Har försökt googla lite men det är inte så lätt när man inte vet vad man ska söka efter. Select, Update, Insert, Delete function kommer det upp hur mycket som helst på. ;)

Om jag lyckas hitta en artikel om detta och kan behärska det så skulle det väll gå att göra så här:

  • En class med get/set sakerna
  • En class som fungerar som ett DAL, där jag använder min SDUI funktion.
  • En class med min SDIU funktion.

Sedan om man har allt det så är det väll bara att i min ObjectDataSource ha TypeName="PunktTvå.GetGuestbook" och DataObjectTypeName="PunktEtt.Guestbook".

Skulle detta sättet vara bra prestanda mässigt eller skulle det vara bättre att skippa ObjectDataSource och DAL och istället bara från min CB köra med SDUI?

Medlem sedan maj 20012 812 inlägg
#39

thvice skrev:

Skulle det inte gå att göra något liknande detta eller är jag helt ute och cyklar?

protected void Page_Load(object sender, EventArgs e)
{
SiteEngine.GetData("SELECT * FROM Table");
Repeater1.DataSource = VadSkaManSkrivaHär?;
Repeater1.DataBind();
}

Det kan man visst gör, varför inte använda koden som jag visat.

protected void Page_Load(object sender, EventArgs e)
{
        DataTable datatable = new DataAccess().ExecuteDataTableResult("MY_CONNECTION_STRING", new SqlCommand("SELECT * FROM Table");
	Repeater1.DataSource = dataTable;
	Repeater1.DataBind();
}

Bör fungera hur bra som helst...

- Magnus

Medlem sedan dec. 2005198 inlägg
#40

Tack Gladh! Precis den koden som jag behövde. ;)
Ska börja pilla med det direkt. och jag antar att prestandan på din kod är ganska hög?
Hur gör man om man kör med SP och parameters på din kod? Och sedan så måste man göra classer eller vad det heter för att kunna köra update, insert och delete också va? Eller har jag missat något?

En fråga till som inte hör till ämnet.
Jag har ett klassbibliotek (tror det heter så) Där alla mina .cs filer ligger. När jag debuggar så kommer det en .dll fil i min bin katalog i mitt projekt. Det som är mest irriterande är att jag måste starta om min debuggning varje gång som jag ändrar något i .cs koden. När alla .cs filer låg i mitt projekt så var det ju bara att uppdatera sidan.
Går det att lösa på något sätt i VS så man bara behöver uppdatera? Igen så kommer min lathet fram. ;)

EDIT

Ja jag missade något, ExecuteScalar. Hur gör man för att använda det?
Vad ska man med results till?

145 ms totalt · 3 externa anrop · v20260731065814-full.4bcf49fe
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
142 ms — hämta tråd, inlägg och bilagor (db)