ארכיון תגיות: Entity Framework Core

EntityFrameworkCore – ירושה ממחלקת בסיס

העיקרון של ירושה בתיכנות מונחה עצמים, יכול לעזור במשהו נחמד בשימוש ב-ORM. לכל טבלה הרי יש בדרך כלל מפתח ראשי, ועמודות "ניהול" כמו created_at , updated_at ולעיתים עוד. מה יותר נחמד מאשר ליצור מחלקת בסיס שתכיל את המאפיינים האלו, וכך נחסוך כמה שורות קוד.

להלן דוגמא למימוש :

 public class EntityBase
 {
 public int Id { get; set; }
 public DateTime CreatedAt { get;set }

 }

 public class Category : EntityBase
 {
 public string CategoryName { get; set; }

 public virtual ICollection<Post> Posts { get; set; }
 }

 public class Post:EntityBase
 {

 public string Title { get; set; }

 public string Content { get; set; }

 public virtual Category Category { get; set; }
 }

זה מאפשר לעשות משהו נוסף – אפשר להשתמש בקונסטרטור של מחלקת הבסיס כדי לשים ערכים מראש לכל המחלקות.

למשל

 public class EntityBase
 {
 public EntityBase()
 {
 CreatedAt = DateTime.Now;

 }

 public int Id { get; set; }
 public DateTime CreatedAt { get;set }

 }

 

EntityFrameworkCore – ליצור תלויות בין ישויות

דרך אחת ליצור תלויות בין ישויות ב- Entity Framework Core היא להכריז על מאפיינים וירטואלים.

למשל – נניח שיש לנו יחס כזה – אחד לרבים קלאסי :

  • פוסט אחד קשור לקטגוריה
  • קטגוריה מכילה פוסטים רבים.

אז נוסיף לקלאס של הפוסט – קישור ל "אבא" הקטגוריה :

 public class Post
 {
 public int Id { get; set; }

 public string Title { get; set; }

 public string Content { get; set; }

 public virtual Category Category { get; set; }
 }

ונוסיף לקלאס של הקטגוריה – קישור ל "בנים" הפוסטים :

public class Category
 {
 public int Id { get; set; }
 public string Category { get; set; }

 public virtual ICollection<Post> Posts { get; set; }
 }

מה הערך של משתנים וירטואלים ? האם אפשר להפוך אותם ללא וירטואלים.

  • כן, אפשר. היתרון הקטן שזה נותן כאשר זה נשאר וירטואלי הוא ב -lazy loading . כלומר טעינת התלויות היא "עצלנית" = במובן שהיא מתרחשת מאליה, ברגע ששלפנו את האבא, ישלפו אוטומטית גם הבנים התלויים בו.. השיטה הזו מסייעת ליעילות
    מכך אפשר להבין שכאשר זה לא וירטואלי – אזי זה לא כך.

 

הסבר נחמד אפשר למצוא כאן.

 

תיעוד רשמי : https://docs.microsoft.com/en-us/ef/core/modeling/relationships 

 

Entity Framework Core – יצירת מודלים וחיבור ל Database

רקע – Entity Framework

Entity Framwork היא ORM של מיקרוסופט, כלומר, כלי (=ספריה) שמשמש בתיכנות לגישה קלה לנתונים, לעבודה קלה יותר עם דאטאבייסים (אך לא רק).

הרעיון מבוסס על כך שיש לנו "מודל" לכל ישות, וכל מודל מקושר לטבלה מסויים ב-DB (רלציוני, ול-collection ב-DB לא רלציוני).

יצירת מודלים ב Entity Framework Core

הרעיון – שמודל מייצג טבלה בדאטאבייס, או ישות אחרת.
לרוב – מודל מייצג טבלה כמו שהיא.
אך קיימים מקרים, בהם מודל מייצג גם יותר שדות מאשר בטבלה ( לדוגמא, כולל שדות מחושבים), או בכלל מייצג ישות שלא קיימת כמות שהיא בדאטאבייס.

במודל – כל שדה, מקביל לשדה בטבלה ( אפשר לבטל את הקישור הזה, אבל לצורך הלימוד, נתמקד באפשרות הרגילה הזו).

שם הטבלה – יכול להיות מקביל *בדיוק* לשם הקלאס, או שאפשר לקבוע אותו באמצעות מאפיין ( Attribute )
בצורה הבאה

[Table("Posts")]
 public class Post
 {

 

לצורך ההדגמה, לפני שניגש להתעסק עם דאטאבייס אמיתי, נתעסק תחילה עם דאטאבייס בזיכרון בלבד, מה שנקרא InMemory
לשם כך נתקין את חבילות הנוגט הבאות :
Microsoft.EntityFramewordCore.InMemory

יש 3 דרכים (לפחות) להתקין חבילות של nuget :

  1.  מקש ימני על הפרוייקט – לבחור באפשרות Manage nuget packages ולחפש ולהתקין את הספריה.
  2. דרך תפריט Tools (או מקש ימני על הפרויקט ) לפתוח את nuget package manager -> Package manager console , ואז להקליד
    Install-package YourPackageExactName
    במקרה כזה – כדי להעתיק את הפקודה המדוייקת מהאתר של nuget.
  3. מקש ימני על הפרוייקט – Edit YOUR_PROJECT_NAME.csproj
    ואז להוסיף ענף בקובץ ה-XML שמכיל את הספריה הרלוונטית .
    ברגע ששומרים את הקובץ, ה-Visual studio מזהה את השינוי, ומתקין את הספריה.

יצירת Context

המונח Context הוא במילים אחרות "חיבור" , כלומר אנחנו הולכים ליצור חיבור לדאטאבייס. בשפות תיכנות אחרות זה נקרא Connection וכדומה. בסופו של דבר מדובר בסה"כ במחלקה עם הגדרות, אותה מחלקה תכיל רשימת מחלקות אחרות – שהם הישויות הרלוונטיות ( ה- Entities ).
ובסופו של דבר, המחלקה הזאת תוזרק (DI ) אל כל מחלקה שצריכה חיבור לדאטאבייס.
בדוגמא הנוכחית אנחנו נגדיר DbContext (=חיבור) אל דאטאבייס בזיכרון.

ניצור מחלקה שנקרא לה ApiContext, ונגדיר שהיא יורשת מ- DbContext .
במחלקה הזאת נגדיר פונקצית קונסטרטור, בצורה המוצגת למטה, ובהמשך, נרשום את שמות הטבלאות, בתור מאפיינים מסוג dbSet של המחלקה.

public class ApiContext : DbContext
 {
 public ApiContext(DbContextOptions<ApiContext> options) : base(options)
 {

}

public DbSet<Post> Posts { get; set; }


 }

עכשיו, נגדיר בקובץ Startap.cs את ההגדרות הנחוצות, כדי שנוכל להזריק את ה- DbContext שיצרנו אל כל מחלקה שתרצה להשתמש בו.
כך זה נראה

 // This method gets called by the runtime. Use this method to add services to the container.
 public void ConfigureServices(IServiceCollection services)
 {
 services.AddDbContext<ApiContext>(options => options.UseInMemoryDatabase("Hi"));
 services.AddMvc();
 }

 

חיבור לדאטאבייס אמיתי

כדי להתחבר לדאטאבייס אמיתי, צריך לעשות כמה דברים :

  • להתקין חבילת nuget, שתהווה את הדרייבר אל הדאטאבייס הספציפי.
  • להגדיר Connection String בקובץ הגדרות, ולדאוג לשלוף את ההגדרה במקום הנכון.

דוגמא 1 : שימוש ב-SqlServer

  • בתור דרייבר — נתקין את חבילת ה nuget שנקראת Microsoft.EntityFrameworkCore.SqlServer
  • לצורך ההגדרה – נפתח את קובץ appsetting.json, ונגדיר בו קטע של ConnectionStrings

השם שהענקתי לאלמנט ה-JSON, כלומר "MyConnectionString", הוא השם שישמש אותי אחר כך ליצור service שמוזרק בעת הצורך.

כדי להקל על כתיבת המחרוזת, השתמשתי ב-Server Explorer שמובנה בתוך Visual Studio.

 "ConnectionStrings": {
 "MyConnectionString": "Data Source=LAPTOP-JD3DQ8JM\\SQLEXPRESS;Initial Catalog=EZCourse;Integrated Security=True"
 }
  • לצורך יצירת ה-service , הוספתי בפונקציה configureServices שנמצאת בקובץ startap.cs את הקטע הבא :
public void ConfigureServices(IServiceCollection services)
 {
 var connectionString = Configuration.GetConnectionString("MyConnectionString");
 services.AddDbContext<Models.AppContext>(options => options.UseSqlServer(connectionString));
 services.AddMvc();
 }