webForumDet fria alternativet

Problem med att översätta ifrån VB-script till Asp.net 2.0 C#

.NET

10 svar · 658 visningar · startad av saw

Medlem sedan mars 20011 880 inlägg
Frågan#1

Jag skulle vara tacksam om någon skulle viljahjälpa mig.
Vb-scriptet ser ut så här:

SQL="SELECT MAX(id) AS maxid FROM Quize"
  Call MakeRecordSet(rst,SQL,Connection)
  Randomize
  Dim Urval(10)
  ' Antal hittills utvalda
  Antal_valda = 0
  ' Håll på tills vi valt 10 stycken
  While Antal_valda < 10
  ' Välj ett tal
     Slumptal = Int(Rnd * rst("maxid")) + 1
  ' Finns talet redan?
  Finns_redan = false
	  For i = 1 to Antal_valda
             	  If Slumptal = Urval(i) Then
		  ' Talet fanns redan
		  Finns_redan = true
		  Exit For
		  End If
	  Next
  ' Om talet inte fanns, lägg det i Urval'
  If Not Finns_redan Then
	  Antal_valda = Antal_valda + 1
	  Urval(Antal_valda) = Slumptal
  End If
Wend
Session("Urval") =	Urval(10)

Jag försöker så här:

sql = "SELECT MAX(id) AS maxid FROM Quize";
        DataSet ds1 = new DataSet();
        OleDbDataAdapter Adapter1 = new OleDbDataAdapter();
        Adapter1.SelectCommand = new OleDbCommand(sql, DBConn);
        Adapter1.Fill(ds1, "Quize");

        string id = ds1.Tables["Quize"].Rows[0]["maxid"].ToString();

int[] Urval = new int [10];
        int antalValda=0;
        int slumpTal=0;
        while (antalValda < 10)
        {
        Random randomNumber = new Random();
        slumpTal = randomNumber.Next(1, Convert.ToInt32(id));
       ' Response.Write(slumpTal.ToString()); 'detta är för att kolla att jag får ett id
        for (int i = 0; i < antalValda; i++)
        {
            if (slumpTal != Urval[i])
            {
                antalValda += 1;
                Urval[antalValda] = slumpTal;
            }
        }

Det som händer, är att sidan börja att laddas in, sen så står den bara och "tänker".
Vad gör jag för fel?

Medlem sedan dec. 19996 721 inlägg
#2

Du hamnar i en evig loop. antalValda är ju 0 från början och i for-loopen kollar du om i<antalValda, vilket det inte är. Alltså kommer antalValda aldrig att bli antalValda+1, och man kommer aldrig ur while-loopen.

BTW. Om du bara ska hämta ett enda värde från databasen så är det ohygglig overkill att köra via en adapter och ett dataset! Använd bara ett OleDbCommand och metoden ExecuteScalar.

Medlem sedan mars 20011 880 inlägg
#3

Tack för svar emission, och jag förstår dina synpunkter, dok inte hur jag skall lösa det.
Jag gjorde en liten test:

for (int i = 0; i < antalValda; i++)
            {
                Random randomNumber = new Random();
                slumpTal = randomNumber.Next(1, Convert.ToInt32(id));
                Response.Write(slumpTal.ToString());
                if (slumpTal != Urval[i])
                {
                    antalValda += 1;
                    Urval[antalValda] = slumpTal;
                }
                    
            }

Jag flyttade in min random, då jag tänkte att den då skulle fylla på antalValda, men
det blev samma resultat.
Hur skall jag komma förbi problemet?

PS
Jag har ändrat databasanropet:

sql = "SELECT MAX(id) AS maxid FROM Quize";
        OleDbCommand myCommand = new OleDbCommand(sql, DBConn);
        DBConn.Open();
        int id = (int)myCommand.ExecuteScalar();

DS

Medlem sedan dec. 2005664 inlägg
#4

Du sitter fortfarande med samma problem. For-satsen säger at den ska gå in i satsen om i är mindre än noll (antalValda). Om du vill att den ska gå in i for-satsen måste du sätta ett annat vilkor, alternativt ändra värdet på antalvalda till något mer än noll.

Medlem sedan sep. 20011 914 inlägg
#5

Gjorde en lottonummer generator för ett tag sen som borde fungera.

string connectionstring = "";
string sql = "SELECT MAX(id) AS maxid FROM Quize";
OleDbConnection conn = new OleDbConnection(connectionstring);
OleDbCommand myCommand = new OleDbCommand(sql, conn);

int max = 0;
using(conn)
{
   conn.Open();
   max = (int)myCommand.ExecuteScalar();
}

if(max == 0)
   throw;

List<int> col = new List<int>();
Random rnd = new Random();
for(int i = 0; i < 7; i++)
{
   int x;
   do 
   {
      x = rnd.Next(1, max);
   }
   while(col.Contains(x));
   col.Add(x);
}            

foreach(int i in col)
   Response.Write(i.ToString() + "<br/>");
Medlem sedan mars 20011 880 inlägg
#6

Dino, det ser väldigt intressant ut, men jag åker på ett par errors.

if (max == 0)
            throw;
'error: Error	1	En throw-sats utan argument tillåts inte utanför en catch-sats	F:\Inetpub\wwwroot\ASP_Net-Test\Saw-Asp.net\Quize\Quize.aspx.cs	52	13	F:\...\Saw-Asp.net\

'om jag bortkommenterar raden med throw;
 List<int> col = new List<int>();
'error
Error	1	En inbäddad sats kan inte vara en deklaration eller etiketterad sats	F:\Inetpub\wwwroot\ASP_Net-Test\Saw-Asp.net\Quize\Quize.aspx.cs	54	9	F:\...\Saw-Asp.net\

Det känns som om jag är i närheten, men jag vet inte hur jag skall fixa till detta.

Medlem sedan dec. 19996 721 inlägg
#7

Om du bortkommenterar raden med throw så blir ju den if-satsen helt uppf***ad. Ta bort hela det blocket (inte rätt) eller kasta en Exception med throw.

Medlem sedan mars 20011 880 inlägg
#8

Helt riktigt emission.
Jag tror att jag har suttit lite för länge med det här, och såg inte den enkla lösningen, att lägga det i ett try/catch block.

Nu fungerar detta, men jag skulle behöva ha något råd för fortsättningen.
Tidigare (i min gammla applikation) så la jag detta i sessions, och gjorde en ny
databas-sökning för varje fråga. Det känns nog inte bra att göra så.
Min tanke är, skulle man kunna göra bara en sql, och lägga resultatet (i.tostring) som
IN i den sql-sats, lägga detta i ett dataset, och skicka med datasetet som ett
agrument till en class?
Finns det något bättre sätt?

Medlem sedan mars 20011 880 inlägg
#9

Jag har gjort så här nu:

sql="SELECT Quize.Id, Quize.Fraga, Quize.Allt1, Quize.Allt2, Quize.Allt3, Quize.Svar, Quize.Ratt FROM Quize ";
        sql +="  WHERE Quize.Id  IN( ";
        foreach (int i in col)
            sql += i.ToString() + ",";
        sql += " )";
        Response.Write(sql);

När jag skriver ut min sql så blir det:

SELECT Quize.Id, Quize.Fraga, Quize.Allt1, Quize.Allt2, Quize.Allt3, 
Quize.Svar, Quize.Ratt FROM Quize WHERE Quize.Id IN( 
49,39,421,94,69,409,239,53,290,34, )

Som ni ser, så får jag med ett "," för mycke, och jag antar att jag skall
ha en if-sats för att känna av om jag är på sista posten.
Men jag vet inte hur den bör utformas. Något tips? :stud

Medlem sedan mars 20011 880 inlägg
#10

Jag såg svårigheterna som större än lösningen:

int k = 1;
        foreach (int i in col)
        {
            if (k != 10)
                sql += i.ToString() + ",";
            else
                sql += i.ToString();
            k += 1;
        }

Tack för all hjälp.

Medlem sedan dec. 19996 721 inlägg
#11

Antingen så gör du en if-sats som struntar i att lägga på kommat om du är på den sista posten (du får göra en for-loop i stället för en foreach), eller så tar du helt enkelt bort sista bokstaven från SQL-satsen.

sql=sql.Substring(0,sql.Length-1);
sql += " )";

PS. Det stavas "Quiz", utan "e" :) DS

269 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
126 ms — deklarationer (db)
0 ms — hämta statistik (cache)
134 ms — hämta tråd, inlägg och bilagor (db)
131 ms — ändringar (db)