קבלתי שאלה כיצד מתחברים לבסיס נתונים ב - net.
כמובן שהפתרון גדול מידי עבור מסגרת הזו, אבל בכל זאת אני אדגים כאן את הבסיס להתחברות בכל השיטות.
חשוב לזכור שפוסט זה הינו דוגמא בסיסית ביותר לגישה בכל השיטות ולא לימוד מעמיק של כל אחת מהם.
(אני מתנצל מראש שהדוגמאות בפוסט זה הם ב - vb.net ולא ב - #C)
הקדמה:
כדי לגשת לבסיס נתונים מ - net קיימים (בעיקר) שלוש דרכים.
הראשונה והבסיסית היא כמובן
ado.net.
השנייה היא גישה בעזרת dataset, typed dataset.
והשלישית היא orm כשהשיטות העיקריות הם nhibernate, entity framework.
ado.net:
ado.net היא השיטה הבסיסית שכל השיטות מאחורי הקלעים עובדים איתה, מדובר על פתיחת חיבורים לבסיס הנתונים, שליחה של פעולות (select, update, insert, delete) וניתוח התוצאות החוזרות מהשאילתא בעצמנו.
דוגמא בסיסית לקריאה וכתיבה לבסיס נתונים בעזרת ado.
בהנתן שיש לנו טבלה בשם names שנראית כך:
נכתוב טופס שיודע להציג ולהוסיף שמות:
כעת נכתוב את הקוד שטוען את כל השמות מבסיס הנתונים ב - ado
Private Sub FillCombo()
ComboBox1.Items.Clear()
Dim cnn As New SqlConnection()
cnn.ConnectionString = "Data Source=.\SQLEXPRESS;" +
"AttachDbFilename=|DataDirectory|\DatabaseDemo.mdf;" +
"Integrated Security=True;User Instance=True"
Dim cmd As New SqlCommand()
cmd.Connection = cnn
cmd.CommandText = "select [Name] from names"
cnn.Open()
Dim reader As SqlDataReader = cmd.ExecuteReader()
While reader.Read()
ComboBox1.Items.Add(reader(0).ToString())
End While
cnn.Close()
End Sub
ראשית ננקה את ה - combo מהנתונים שיש בו.
לאחר מכן נייצר מופע של SqlConnection ונגדיר לו את ה - ConnectionString - שזה הכתובת היכן בסיס הנתונים יושב.
נגדיר אובייקט מסוג SqlCommand ונגדיר לו את ה - Connection ואת ה - Command - שהיא מה השאילתא שנרצה להריץ.
כעת אנחנו פותחים את ה - Connection ולאחר מכן נפעיל את פונקצית ExecuteReader - שמחזירה אובייקט מסוג SqlDataReader - שיודע לקרוא את הנתונים מתוצאות השאילתא.
כמובן שנזכור לסגור את ה - Connection.
באירוע Load של הטופס נקרא לפונקציה FIllCombo.
בנוסף בקוד של הלחצן הוספת שם חדש, נכתוב את הקוד הבא:
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim cnn As New SqlConnection()
cnn.ConnectionString = "Data Source=.\SQLEXPRESS;" +
"AttachDbFilename=|DataDirectory|\DatabaseDemo.mdf;" +
"Integrated Security=True;User Instance=True"
Dim cmd As New SqlCommand()
cmd.Connection = cnn
cmd.CommandText = "insert into names values(@name)"
cmd.Parameters.AddWithValue("name", TextBox1.Text)
cnn.Open()
cmd.ExecuteNonQuery()
cnn.Close()
FillCombo()
End Sub
עד השורה של הגדרת ה - CommandText הקוד זהה לפונקציה הקודמת.
הגדרת ה - CommandText - מגדירה שאילתת Insert עם שימוש בפרמטר בשם name (אפשר היה לשרשר את הערך מתיבת הטקסט - אבל זה גורם לבעיית אבטחה בשם
Sql Injection)
אחרי שה - Connection נפתח נשתמש ב - ExecuteNonQuery מכיוון שהפעם אנחנו שולחים שאילתא שהיא לא Select.
כמובן שבקוד בסביבה אמיתית נדאג לכך שלא נצטרך לשכפל קוד ושהערך של ה - ConnectionString יהיה בקובץ קונפיג ולא בקוד.
dataset:
חלופה ותיקה של עבודה עם ado.net הסטנדרטי זה עבודה עם dataset - dataset מייצג בזיכרון database ומכיל אובייקטים מסוג datatable, datacolumn, datarow וכן הלאה המייצגים בזיכרון מידע מבסיס הנתונים.
ישנם שני סוגים של עבודה עם dataset, הראשונה dataset רגיל שבו נעבוד עם שמות הטבלאות והעמודות בעזרת indexer של שמות, כלומר נוכל לראות קוד כזה:
DataTable table = set["tableName"];
השיטה העדיפה היא עבודה עם Typed dataset - בו נגדיר מראש את הטבלאות וסביבת העבודה תייצר עבורנו מחלקות עבור כל טבלה, לדוגמא נוכל לראות קוד כזה:
NamesDataTable table = set.Names;
ראשית נוסיף לפרויקט קובץ מסוג dataset - נגדיר לו שם כלשהו (בדוגמא - dataset1)
מה - server explorer נגרור את הטבלה שלנו.
בסוף התהליך זה יראה כך:
כפי שאפשר לראות - נוצר טבלה בשם Names ובנוסף NamesTableAdapter שתפקידו להריץ את השאילתות עבור ה - dataset.
כעת נראה את הקוד שלנו (שיהיה הרבה יותר פשוט)
Dim ds As DataSet1
Dim adpter As NamesTableAdapter
Private Sub Form3_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
FillComboBox()
ComboBox1.DataSource = ds.Names
ComboBox1.DisplayMember = "Name"
End Sub
Private Sub FillComboBox()
ds = New DataSet1()
adpter = New NamesTableAdapter()
adpter.Fill(ds.Names)
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
ds.Names.AddNamesRow(TextBox1.Text)
adpter.Update(ds.Names)
End Sub
ראשית יש לנו הגדרה של אובייקט מסוג DataSet1 ו - NamesTableAdapter.
במתודת FillComboBox ניצור מופע חדש שלהם, ונשתמש במתודה מיוחדת של ה - adapter בשם Fill שמקבל כפרמטר את הטבלה שלתוכה הוא צריך למלאות את הנתונים.
באירוע Load, לאחר הקריאה למתודה, ניתן את הטבלה כפרמטר ל - DataSource של ה - Combo ונגדיר איזה עמודה תוצג.
בלחיצה על הוספה, נוסיף שורה חדשה לטבלה ונפעיל את פונקציית Update כדי לשמור בבסיס הנתונים.
orm:
object relations mapping הינו רעיון המדבר על עבודה עם אוביקטים בלי לחשוב (כמעט) על בסיס נתונים. ההבדל המרכזי (ברעיון ולא בטכנולוגיה) בינו לבין dataset, שב - dataset אנחנו עובדים ומדברים על מושגים של טבלאות שורות ועמודות, לעומת orm שבו אנחנו עובדים עם אובייקטים ו - object oriented.
יש כמה מימושים ל - orm, הותיקה ביותר היא nhibernate, והטובה ביותר (לדעתי) היא
entity framework.
נראה דוגמא לעבודה עם entity framework.
נוסיף קובץ מסוג ADO.Net Entity Data Model (סיומת edmx)
יפתח wizard שישאל האם אנחנו רוצים מודל ריק או מודל שיווצר מבסיס הנתונים, נבחר מבסיס הנתונים, לאחר מכן הוא יבקש את ה - Connection String ואת הטבלאות שנרצה להוסיף.
בסוף התהליך נקבל את הדבר הבא:
כעת נוכל לכתוב את הקוד הבא:
Dim context As New DatabaseDemoEntities()
Private Sub Form4_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
ComboBox1.DataSource = context.Names
ComboBox1.DisplayMember = "Name"
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
context.Names.AddObject(NameObject.CreateNameObject(0, TextBox1.Text))
context.SaveChanges()
ComboBox1.DataSource = context.Names.ToArray()
End Sub
באירוע Load ניתן את המאפיין Names כמקור מידע ל - ComboBox.
ובפונקצית Add נוסיף אוביקטים חדשים.
לסיכום:
אין שיטה נכונה יותר או נכונה פחות לעבודה עם בסיס הנתונים, כל השיטות הם נכונות - השאלה היא מהו הפרויקט ועל מה מדובר. ההחלטה כיצד לדבר עם בסיס הנתונים היא החלטה שצריך לחשוב עליה ולא להחליט כלאחר יד.
מהנסיון שלי - העבודה הכי פשוטה וקלה היא שיטת orm עם Entity Framework 4.0 (הגרסאות שלאחר מכן הם יותר מסובכות ומתאימות לפרוייקטים גדולים יותר שעובדים עם ארכיטקטורות מסוימות).
כמובן פוסט זה הוא רק נגיעה בכל אחת מהשיטות, ולא משנה מה תבחרו תצטרכו להעמיק בנושא כדי לדעת לכתוב ולעבוד בצורה נכונה.