מצגת 01
שכבת הנתונים
DataAccessLayer
איך ישות אחת הופכת לטבלה ב-DB, בלי SQL ידני ובלי מיגרציות.
מה תפקיד השכבה?
- כל הגישה לבסיס הנתונים עוברת כאן — אף שכבה אחרת לא כותבת SQL.
- ORM קטן וממוקד משלנו:
Record+ אטריביוטים, בלי Entity Framework. - תומכת בשלושה ספקים באותו קוד בדיוק: SQL Server, MySQL, SQLite.
- אסינכרונית מקצה לקצה — כל פנייה ל-DB היא
await, אף Thread לא נחסם.
Record — הלב של השכבה
- לכל ישות יש
ID(מפתח ראשי) ו-Description. - מסמנים תכונה ב-
[Column]— והיא עמודה ב-DB. - שם הטבלה = שם המחלקה; המפתח =
שם+Id. - אין ALTER ידני:
SetupAsyncבעליית האפליקציה יוצרת טבלאות חסרות ומוסיפה/מרחיבה עמודות לפי הקוד.
public class Car : Record
{
[Column(Size = 300)]
public override string Description { get; set; }
[Column] public bool IsAutomatic { get; set; }
[Column] public double Volume { get; set; }
[Column] public string Color { get; set; }
[Column] public DateTime ProductionDate { get; set; }
}
זהו כל הקוד שנדרש כדי שטבלת Car תקום ב-DB ותנוהל במסך.
CRUD אסינכרוני
Car c = new Car { Description = "מאזדה 3", Volume = 2.0 };
await c.SaveAsync(); // INSERT (ID חדש) או UPDATE — אוטומטית
Car loaded = await Record.GetAsync<Car>(c.ID); // טעינה לפי מפתח
List<Car> all = await Record.AllAsync<Car>(); // כל הרשומות
int n = await Record.CountAsync<Car>(); // ספירה
c.Color = "אדום";
await c.UpdatePropertiesAsync("Color"); // עדכון עמודה בודדת — לא Save מלא!
await c.DeleteAsync();
- כלל בית: עדכון נקודתי =
UpdatePropertiesAsync, לאSaveAsync— כדי לא לגרור תופעות לוואי של שמירה מלאה. DateTime.MinValueפירושו "אין תאריך" — נשמר כ-NULL.
שאילתות מסוננות — AndFilter
AndFilter f = new AndFilter();
f.Add("color", "אדום"); // שוויון, עם פרמטר
f.Add("volume", 1.6, EqalityOperators.GreaterThan);
f.AddBetween("productionDate", from, to);
List<Car> cars = await Record.PartialAsync<Car>(f, "productionDate desc",
pageNumber: 0, pageSize: 20);
int total = await Record.CountAsync<Car>(f);
- הפילטר בונה WHERE עם פרמטרים — בלי שרשור מחרוזות ובלי SQL Injection.
OrFilterמשלים תנאי "או"; עימוד דרךPagingTemplateשל כל ספק.
איך אותו קוד רץ על שלושה בסיסי נתונים?
- הספק נבחר לפי מחרוזת החיבור:
Server=← MySQL, Data Source=*.db← SQLite, אחרת ← SQL Server. - הקוד כותב T-SQL;
FixSqlשל כל ספק מתרגם: GETDATE(), ISNULL, [סוגריים], IDENTITY… - SQLite מקבל גם פונקציות
YEAR/MONTH/DAYשהוגדרו ב-C#. - פיתוח מקומי על SQLite, ייצור על SQL Server/MySQL — בלי לשנות שורה.
עוד כלים בארגז
- הצפנה:
[Column(IsEncrypted = true)]— הערך מוצפן AES לפני הכתיבה ומפוענח בקריאה. - סריאליזציה:
SerializeType = Jsonשומר אובייקט שלם בעמודת טקסט. - אינדקסים:
CreateIndexAsync("color")— נוצר רק אם אינו קיים, בכל ספק. - ייבוא:
ImportAsyncמזהה רשומות קיימות לפיIsUniqueIdומעדכן במקום לשכפל. - טרנזקציות:
BeginTransactionAsync / CommitTransactionAsync.
לסיכום: מגדירים ישות, מסמנים עמודות — והשכבה עושה את כל השאר.