14. november 2010 - 05:57Der er
5 kommentarer og 1 løsning
Kan dette goeres nemmere?
Jeg har et felt i en SqlServer tabel, som hedder "friends". Strukturen er saadan her:
23423|534534|345|2423|5656|4564
Userids splittet med pipe.
Naar jeg vil tilfoeje en ny ven, skal min metode putte den nye ind foerst, saadan her:
NYVENID|23423|534534|345|2423|5656|4564
Jeg har lavet en metode, som foerst henter strengen, derefter laegger den nye streng foerst og derefter tager de 99 naeste, saaledes at der altid kun er max 100. Metoden ser saadan her ud:
public int AddToFriends(int userid, int friendid) { int result = 0; string sql1 = "SELECT friends FROM lfstats WHERE userid=@userid"; string currentfriends, newfriends; try { using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["lfcs"].ToString())) using (SqlCommand cmd = new SqlCommand(sql1)) { con.Open(); cmd.Connection = con; cmd.CommandType = CommandType.Text; using (SqlDataReader rdr = cmd.ExecuteReader()) { if (rdr.Read()) currentfriends = rdr["friends"].ToString(); } } } catch (SqlException e) { throw e; } int[] friendsarr = currentfriends.Split(new char[] { '|' }); newfriends = friendid.ToString(); int i = 0; while (i < friendsarr.Length) { if (i < 99) { newfriends += "|" + friendsarr[i]; } i++; } string sql2 = "UPDATE lfstats SET friends=@newfriends WHERE userid=@userid"; string sql3 = "DELETE FROM lfpendingfriend WHERE fromid=@friendid AND toid=@userid"; try { using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["lfcs"].ToString())) using (SqlCommand cmd = new SqlCommand(sql2)) { con.Open(); cmd.Connection = con; cmd.CommandType = CommandType.Text; cmd.Parameters.Add("@newfriends", SqlDbType.NVarChar).Value = newfriends; result = cmd.ExecuteNonQuery(); cmd.CommandText = sql3; cmd.Parameters.Add("@friendid", SqlDbType.Int).Value = friendid; cmd.Parameters.Add("@userid", SqlDbType.Int).Value = userid; result = cmd.ExecuteNonQuery(); } } catch (SqlException e) { throw e; } return result; }
Som det ses er der 3 sql statements, 2 sqlconnections og hvad ved jeg :) Kan jeg ikke goere dette nemmere (og hurtigere), maaske med bedre SQL statements?
Jeg tror reelt at databasen er bedre end dig til at håndtere relationer. Og den måde du prøver at relatere en friend til en user er ikke den bedste måde at gøre det på.
Hvis du insisterer, så brug i det mindste string.Join("|"friendsarr) til at lave din string.
Men det bedste ville nok være at lave en ny tabel:
UserId | FriendId | DateAdded
Og så hver gang din user får en ny ven, så INSERT INTO UserFriends values (UserId, FriendId, DateAdded)
Og når du skal hente din users friends:
select FriendId from UserFriends where userId = @userId order by DateAdded desc
Ja det giver jo mening og goer det hele lidt lettere med en tabel mere ;) Ved ikke hvorfor jeg ville have den streng. Du kan bare svare :) Men nu hvor jeg har dig; kan man fyre 2 eller flere sql statements af paa een gang (i een commandtext), saaledes at:
using (SqlCommand cmd = new SqlCommand(sql2)) { con.Open(); cmd.Connection = con; cmd.CommandType = CommandType.Text; cmd.Parameters.Add("@newfriends", SqlDbType.NVarChar).Value = newfriends; result = cmd.ExecuteNonQuery(); cmd.CommandText = sql3; cmd.Parameters.Add("@friendid", SqlDbType.Int).Value = friendid; cmd.Parameters.Add("@userid", SqlDbType.Int).Value = userid; result = cmd.ExecuteNonQuery(); }
Du kan kun fyre 1 statement af pr. kald, men du kan jo bare kalde den flere gange med samme connection, hvilket vil køre bedre end at oprette connection 2 eller 3 gange.
Men lige en advarsel, du skal ikke dermed tro at jeg mener din connection skal forblive åben, man skal altid lukke den pænt igen når du er færdig.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.