JonMedlem sedan juli 20011 304 inlägg Hur gör ni för att åstadkomma paging i .NET?
Jag vill inte heller använda stored procedures.
Det känns som det obönhörligen blir två frågor till databasen:
1. Hur många sidor resulterar min fråga i med antalposter/sida
2. Ge mig sida y vid antalposter/sida
Detta måste jag då bygga upp i ren sql. Känns oeffektivt men nödvändigt. Eller gör någon på något bättre sätt kanske? :)
Denna kod använder jag för min paging: Paging med DataSet och PagedDataSource. Fungerar finfint och är enkel att bygga vidare på. :D
JonMedlem sedan juli 20011 304 inlägg Jo så kan man ju göra men jag har 10000 stora poster och har inte för avsikt att ladda in samtliga i minnet :)
Just nu returnerar jag en ArrayList med massa objekt i. Det skulle inte vara svårt att returnera en sida istället. Men det förutsätter ju att jag antingen även returnerar antal sidor på något sätt eller ställer en till fråga till databasen...
I dagsläget så har jag en PagedRepeater där jag egentligen sätter hela resultatet som datakälla och sen bara visar pageSize antal poster och genererar länkar till restrerande sidor. Funkar ju som sagt fint på små saker men det börjar bli lite oeffektivt!
Du kan ju plocka ut säg 100 senaste posterna, och sen generera länkar till resterande sidor med poster. Kör en enkel
SELECT Count(unikt falt) FROM tabell as x
som en underfråga i din huvudsakliga SQL-fråga. Sen är det med några villkorssatser inte alltför svårt att generera länkar utifrån antalet poster som finns i databastabellen (exkl. exempelvis de 100 första du alltid plockar ut).
GladhMedlem sedan maj 20012 812 inlägg Jon du har nog inte riktigt förstått vad en SP är/gör.
En SP är ren SQL med möjlighet att göra mer avancerade saker i. Om du lyckas med en ren SQL sats så kan du lägga den i en SP och vips så har du en SP som klarar det du vill.
Du är uteefter en SQL paging funktion och använder du dig av Access/MS SQL Server så blir det jobbigt, det finns mer/mindre bra lösningar på Paging funktioner i SPs för SQL Server.
Använder du dig av MySQL/Oracle så finns det inbyggda funktioner för att hämta ut en delmängd i ditt recordset.
En annan lösning är att du hämtar alla din 10000 objekt, lägger dessa i en Array, stoppar array i cachen och sedan hämtar du 10 objkt åt gången från din array i cachen. Fördelen här är att du endast gör 1 databanrop oberoende av hur många besökare du har på din sida, detta spar prestand både för din webserver men framför allt prestenad för SQL Server (om du har många besökare). Det tar ju dock lite tid första gången, som posterna anropas, och det krävs ju att du har mycket ramminne i maksinen, tänk om du har 1000 poster och varje post tar 1 MB i utrymme. Helt plötslig så har du tagit upp 1GB internminne för din array i cachen.
- Magnus
JonMedlem sedan juli 20011 304 inlägg Jo jag har mycket väl förstått vad stored procedures gör.
Men nu är faktum det att jag inte får använda mig av dem. Har alltid gjort det innan och skapat en temptabell och hämtat ut delmängeder och skapat sidor av. Mycket snabbt, lätt och smidigt.
Nu är jag som tidigare sagt ute efter ett alternativ (som inte innefattar att ladda flera hundra megabyte i webbserverns eller applikationsserverns minne) :)
GladhMedlem sedan maj 20012 812 inlägg Tvärr har MS Sql Server och Access den begränsingen att detta inte låter sig göras på ett effektivt sätt. Givetviss så går det! Men om du vill kunna göra det dynamiskt och effektivt så går det inte.
Här har du några förslag:
1. Du sorterar alltid efter ett fallande löpnummer och kan på detta vis välja följande SQL sats:
"SELECT TOP 10 * FROM [tabell] WHERE ID > " & myId
2. Du kan plocka ut en del mängd med NOT IN
"SELECT TOP 10 * FROM [Tabell] WHERE ID NOT IN (SELECT TOP XX ID FROM TABLE)"
Där XX byts ut mot önskad mängd som inte skall visas. Typ 10,20,30 osv osv...
Läste någonstans att Yukoon skulle få RowNum precis som i ORACLE, då blir det riktigt lätt att hämta ut en delmängd, tyvärr så är det ju ett tag innan den släpps.
Men nu är faktum det att jag inte får använda mig av dem
Vet inte vem som har gett dig den ordern, men personen ifråga kan då inget om Databaser och borde vara tyst.
- M
Testa om nedanstående funkar för dig.
SELECT *, (SELECT count(*) FROM Products) as TotAntal FROM
(SELECT TOP 10 * FROM --Sidstorlek
(SELECT TOP 300 * FROM Products --sidstorlek * sidnummer
ORDER BY ProductID) AS t1
ORDER BY ProductID DESC) AS t2
ORDER BY ProductID
JonMedlem sedan juli 20011 304 inlägg Funktionaliteten i fråga är en del av ett DAL
Det är som tidiage nämts ganska enkelt men MySql och oracle. Jag gör ungefär som drunken_master skrev just nu för sql-server. Det jag ville ta reda på var om någon visste något effektivare sätt :)
Inser mer och mer att det handlar om ren SQL, postade i sql-forumet.
Jag kan ju inte förutsätta att det alltid finns en sp som sköter det hela för sql-server för samtliga tabeller jag vill hämta datasidor från. Eller det kanske är i särklass bäst att skapa en/flera sådana? Jag är öppen för att påverka mina kravställare om jag har bra argument på fötterna! :)
Varför postade jag i asp.net då? Jo det jag även vill hitta den effektivaste lösningen på är att returnera antalet poster totalt eftersom jag vill skriva ut länkar till första, sista och andra sidor emellan.
GladhMedlem sedan maj 20012 812 inlägg Jag är av den uppfattningne att Paging inte skall ligga i ett DAL. Ett dal skall endast exekvera SQL/SqlCommands som kommer in till de, några smarta funktioner som Paging eller övrigt skall inte ligga i DAL. Ditt DAL skall vara så "dumt" som möjligt.
Vill du implementerar Paging så skapar du typ ett eget DataSet och löser det där i. Det kommer dock i slutändan ändå handla om ren SQL som exekveras genom ditt DAL. Men funktionalliteten bör inte ligga i DALet.
- M
GladhMedlem sedan maj 20012 812 inlägg
Jag är öppen för att påverka mina kravställare om jag har bra argument på fötterna!
Det går inte att lösa effektivit i MS SQL Server med endast SQL. Det borde ju vara argument nog.
- M
JonMedlem sedan juli 20011 304 inlägg
Jag är av den uppfattningne att Paging inte skall ligga i ett DAL
Då är vi av olika uppfattningar :)
Eftersom det löses olika beroende på vilken dbms man använder är det det enda stället jag i huvud taget kan se att det kan ligga...
Jag har en O/R mapper som används typ:
CCriteria c = new CCriteria();
c.AddComparition(new CComparition("UsrContext",context,ComparitionType.IS));
return TheObjectMaster.GetBroker().RetrieveObjects(typeof(UserClass),c,RetrieveType.SIMPLE);
Jag vill ropa på:
return theObjectMaster.GetBroker().RetrieveObjectsPaged(typeof(UserClass),c,RetrieveType.SIMPLE,10,5);
O/R-mappern använder sedan aktuell DAL och ber den bygga en SelectPage istället för en vanlig select.
O/R-mappern låter sedan aktuell DAL exekvera sql-satsen.
Man får desan tillbaka en ArrayList med objekt 50 till 60
icaaq »
Tack, då hänger jag med. :i
En fråga till:
Vad är ett BL och vad är en O/R Mapper (OR/Mapper)? :)
VimpMedlem sedan juli 20022 537 inlägg BL = Business Layer
O/R Mapper är om jag har förstått det rätt ett sätt att hantera data på. Det är för att man ska slippa SQL-satser.
Förmodligen har jag helt fel och kommer bli krossad av Gladh eller någon annan :OO :e
Tack, Vimp.
Slippa SQL-frågor? Hur ska man då plocka ut data från en databas?
Nog för att MS har gått ifrån det lite med att sätta in funktioner i några webbserverkontroller, men hur ska man helt komma ifrån SQL-frågor? Hm..
JonMedlem sedan juli 20011 304 inlägg O/R mapper = object/Relational mapper. Man mappar sina objekt till tabeller i en databas. Detta för att kunna programmera helt objektorienterat. Relationsdatabaser har en tendens att slå sönder objektorientering.
Det är inte så att man slipper sql men man gör det bara ordentligt en gång när man bygger sitt DAL som O/R-mappern använder istället för att göra det hundratals :) Den som sedan använder O/R mappern behöver sedan inte använda någon sql.
Det fungerar lite olika beroende på hur o/r mappern är uppbyggd.
I mitt fall gör jag så att jag skapar klasser som håller min data i applikationen. Dessa mappas sedan till tabeller i databasstrukturen antingen med metatdata i en xml-fil eller med attribut i klasserna.
O/R-mappern läser sedan av mappningarna och sparar och hämtar data från rätt tabeller och bygger upp objekten. Den pratar i sin tur med ett DAL som hanterar genereringen av sql för olika databaser.
För att t.ex hämta alla användare i ett system på detta sätt skapar man först en UserClass som man mappar mot kolumnerna och anger relationer till andra objekt.
Sedan ber man bara o/r-mappern att hämta alla Objekt av typen UserClass. Vill man göra ett urval så skapar man ett Critera-objekt (en del av o/r mapping ramverket) och slänger med :)
Samma sak gäller för uppdatering och radering.
Detta är ursprungskällan till denna tråd. Jag vill nämligen se till att den sql-kod jag har skapat är så effektiv som möjligt eller höra om någon kanske använde sig av någon annan teknik för att åstadkomma paging som är effektivare. Det försvann lite nånstans på vägen
GladhMedlem sedan maj 20012 812 inlägg
O/R-mappern använder sedan aktuell DAL och ber den bygga en SelectPage istället för en vanlig select.
O/R-mappern låter sedan aktuell DAL exekvera sql-satsen.
Man får desan tillbaka en ArrayList med objekt 50 till 60
Håller med att DAL:en skall exekvera SQL satsen, håller dock inte med om att den skall genererar något SelectPage. Om du inte vill att din O/R mapper skall generera denna SQL, så hade jag lagt ytterligare ett lager mellan din O/R mapper och din DAL.
Du får givetviss göra precis som du vill, men jag tycker fortfarande att din DAL skall vara så dum som möjligt.
Angående Paging, så kan du inte lösa det effektivt med endast SQL i MS SQL Server/Access. Tyvärr det är den grymma verkligheten som MS har satt oss i.
- M