ΠΠΎΠ»Π»Π΅ΠΊΡΠΈΡ Π²ΠΎΠΏΡΠΎΡΠΎΠ² β Π½Π° ΡΠΎΠ±Π΅ΡΠ΅Π΄ΠΎΠ²Π°Π½ΠΈΠΈ Π² C# π§
ΠΠ±Π·ΠΎΡ Π²ΠΎΠΏΡΠΎΡΠΎΠ² ΠΏΠΎ ΡΠ·ΡΠΊΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΠΈΡΠΎΠ²Π°Π½ΠΈΡ C# ΠΈ ΡΠ΅Ρ
Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ NET
Project maintained by Dvurechensky-Docs
Hosted on GitHub Pages — Theme by mattgraham
ποΈ ΠΠ°ΠΊ ΠΏΠΈΡΠ°ΡΡ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ ΠΊ Π±Π°Π·Π΅ Π΄Π°Π½Π½ΡΡ
ΠΈΠ· .NET?
β¨ ΠΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅
β¬ ΠΠ΅ΡΠ½ΡΡΡΡΡ ΠΊ Π³Π»Π°Π²Π½ΠΎΠΉ
1οΈβ£ ΠΠΎΡΠ΅ΠΌΡ ΡΡΠΎ Π²Π°ΠΆΠ½ΠΎ
ΠΠ΅ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½Π°Ρ ΡΠ°Π±ΠΎΡΠ° Ρ Π±Π°Π·ΠΎΠΉ Π΄Π°Π½Π½ΡΡ
ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠΈΠ²Π΅ΡΡΠΈ ΠΊ:
- ΠΠ΅Π΄Π»Π΅Π½Π½ΡΠΌ Π·Π°ΠΏΡΠΎΡΠ°ΠΌ ΠΈ ΡΠ°ΠΉΠΌΠ°ΡΡΠ°ΠΌ.
- ΠΠ΅ΡΠ΅Π³ΡΡΠ·ΠΊΠ΅ ΡΠ΅ΡΠ²Π΅ΡΠ° ΠΠ.
- ΠΡΡΠΎΠΊΠΎΠΌΡ ΠΏΠΎΡΡΠ΅Π±Π»Π΅Π½ΠΈΡ ΠΏΠ°ΠΌΡΡΠΈ Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ.
- Β«N+1Β» ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°ΠΌ ΠΏΡΠΈ ORM.
- ΠΠ΅ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΠΉ ΡΠ°Π±ΠΎΡΠ΅ ΠΊΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΈ ΠΈΠ½Π΄Π΅ΠΊΡΠΎΠ².
2οΈβ£ ΠΡΠ½ΠΎΠ²Π½ΡΠ΅ ΡΡΡΠ°ΡΠ΅Π³ΠΈΠΈ Π΄Π»Ρ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΡΡ
Π·Π°ΠΏΡΠΎΡΠΎΠ²
a) ΠΡΠ±ΠΎΡ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠ³ΠΎ ORM ΠΈΠ»ΠΈ ΡΡΠΎΠ²Π½Ρ Π΄ΠΎΡΡΡΠΏΠ°
- ADO.NET β ΠΏΡΡΠΌΠΎΠΉ ΠΊΠΎΠ½ΡΡΠΎΠ»Ρ, ΡΠ°ΠΌΡΠΉ Π±ΡΡΡΡΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ, Π½ΠΎ ΡΡΠ΅Π±ΡΠ΅Ρ ΡΡΡΠ½ΠΎΠ³ΠΎ Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΡ SQL ΠΈ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ.
- Dapper β ΠΌΠΈΠΊΡo-ORM, Π±ΡΡΡΡΡΠΉ, Π»Π΅Π³ΠΊΠΎΠ²Π΅ΡΠ½ΡΠΉ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ SQL Π½Π°ΠΏΡΡΠΌΡΡ.
- EF Core / NHibernate β ΡΠ΄ΠΎΠ±Π½ΡΠΉ, Π½ΠΎ Π΅ΡΡΡ Π½Π°ΠΊΠ»Π°Π΄Π½ΡΠ΅ ΡΠ°ΡΡ
ΠΎΠ΄Ρ.
ΠΠ°Π²Π΅ΡΠ·Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ: Π½Π° ΡΠΎΠ±Π΅ΡΠ΅Π΄ΠΎΠ²Π°Π½ΠΈΠΈ ΠΌΠΎΠ³ΡΡ ΡΠΏΡΠΎΡΠΈΡΡ, ΠΊΠΎΠ³Π΄Π° EF Core Π±ΡΡΡΡΠ΅Π΅ ADO.NET ΠΈ ΠΊΠΎΠ³Π΄Π° Π½Π°ΠΎΠ±ΠΎΡΠΎΡ. ΠΡΠ²Π΅Ρ: EF Core ΡΠ΄ΠΎΠ±Π΅Π½, Π½ΠΎ Π΄Π»Ρ ΠΌΠ°ΡΡΠΎΠ²ΡΡ
ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ ΠΈΠ»ΠΈ ΡΠ»ΠΎΠΆΠ½ΡΡ
Π°Π³ΡΠ΅Π³Π°ΡΠΈΠΉ ADO.NET/Dapper Π±ΡΠ΄Π΅Ρ Π±ΡΡΡΡΠ΅Π΅.
b) Π€ΠΈΠ»ΡΡΡΠ°ΡΠΈΡ Π½Π° ΡΠ΅ΡΠ²Π΅ΡΠ΅, Π° Π½Π΅ Π² ΠΏΠ°ΠΌΡΡΠΈ
var data = context.Users.ToList().Where(u => u.IsActive);
var data = context.Users.Where(u => u.IsActive).ToList();
- ΠΠΎΡΡΠ½Π΅Π½ΠΈΠ΅: Π² ΠΏΠ΅ΡΠ²ΠΎΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅
ToList()
Π²ΡΡΡΠ³ΠΈΠ²Π°Π΅Ρ Π²ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅, Π° ΡΠΈΠ»ΡΡΡΠ°ΡΠΈΡ ΠΈΠ΄ΡΡ Π² ΠΏΠ°ΠΌΡΡΠΈ β Π½Π°Π³ΡΡΠ·ΠΊΠ° Π½Π° ΠΏΠ°ΠΌΡΡΡ ΠΈ ΡΠ΅ΡΡ.
c) ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡΠΎΠ΅ΠΊΡΠΈΠΉ
- ΠΠ΅ Π²ΡΡΠ°ΡΠΊΠΈΠ²Π°Π΅ΠΌ Π²ΡΡ: ΡΠΎΠ»ΡΠΊΠΎ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΡΠ΅ ΠΏΠΎΠ»Ρ.
var data = context.Users
.Where(u => u.IsActive)
.Select(u => new { u.Id, u.Name })
.ToList();
- ΠΠ°Π²Π΅ΡΠ·Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ: ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΡΡΠΈΡΠ°ΡΡ, ΡΡΠΎ
Select
ΠΌΠ°Π»ΠΎ Π²Π»ΠΈΡΠ΅Ρ. ΠΠ° Π±ΠΎΠ»ΡΡΠΈΡ
ΡΠ°Π±Π»ΠΈΡΠ°Ρ
Π²ΡΠ³ΡΡΠ·ΠΊΠ° Π²ΡΠ΅Ρ
ΠΊΠΎΠ»ΠΎΠ½ΠΎΠΊ β ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠ°Ρ ΠΎΡΠΈΠ±ΠΊΠ°.
d) ΠΡΠ»ΠΎΠΆΠ΅Π½Π½ΠΎΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ (Deferred Execution)
- LINQ-Π·Π°ΠΏΡΠΎΡΡ Π² EF Core ΡΡΡΠΎΡΡ SQL, Π½ΠΎ Π½Π΅ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ ΡΡΠ°Π·Ρ.
var query = context.Users.Where(u => u.IsActive); // Π΅ΡΡ Π½Π΅ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ
var list = query.ToList(); // Π·Π΄Π΅ΡΡ SQL Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ
- ΠΠ°Π²Π΅ΡΠ·Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ: ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅
foreach
Π²ΠΌΠ΅ΡΡΠΎ ToList()
ΠΈΠ½ΠΎΠ³Π΄Π° ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡ ΠΊ ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΠΌ SQL-Π·Π°ΠΏΡΠΎΡΠ°ΠΌ (N+1 ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°).
e) Avoid N+1 problem
- N+1 ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°: Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π·Π°ΠΏΠΈΡΠΈ Π΄Π΅Π»Π°Π΅ΡΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΉ Π·Π°ΠΏΡΠΎΡ.
// ΠΠ»ΠΎΡ
ΠΎ
var users = context.Users.ToList();
foreach(var user in users)
var roles = context.Roles.Where(r => r.UserId == user.Id).ToList();
// Π₯ΠΎΡΠΎΡΠΎ
var usersWithRoles = context.Users.Include(u => u.Roles).ToList();
- ΠΠ°Π²Π΅ΡΠ·Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ:
Include
Π³ΡΡΠ·ΠΈΡ Π²ΡΠ΅ ΡΠ²ΡΠ·Π°Π½Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅, ΡΡΠΎ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΡΠΆΠ΅Π»ΠΎ Π½Π° Π±ΠΎΠ»ΡΡΠΈΡ
ΡΠ°Π±Π»ΠΈΡΠ°Ρ
β ΠΈΠ½ΠΎΠ³Π΄Π° Π»ΡΡΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠ΅ ΠΏΡΠΎΠ΅ΠΊΡΠΈΠΈ.
f) ΠΠ°Π³ΠΈΠ½Π°ΡΠΈΡ
- ΠΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π²ΡΡΠ°ΡΠΊΠΈΠ²Π°ΡΡ ΠΌΠΈΠ»Π»ΠΈΠΎΠ½Ρ ΡΡΡΠΎΠΊ.
var page = context.Users
.OrderBy(u => u.Id)
.Skip((pageNumber-1) * pageSize)
.Take(pageSize)
.ToList();
- ΠΠ°Π²Π΅ΡΠ·Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ: Π±Π΅Π·
OrderBy
SQL Server Π²ΡΠ΄Π°ΡΡ Π½Π΅ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·ΡΠ΅ΠΌΡΠΉ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ ΠΏΡΠΈ Skip
.
g) ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈΠ·ΠΎΠ²Π°Π½Π½ΡΡ
Π·Π°ΠΏΡΠΎΡΠΎΠ²
- ΠΠ»Ρ Π·Π°ΡΠΈΡΡ ΠΎΡ SQL Injection:
var user = context.Users
.FromSqlRaw("SELECT * FROM Users WHERE Name = {0}", userName)
.ToList();
- ΠΠ°Π²Π΅ΡΠ·Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ: Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ string interpolation Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠΌ Π²Π²ΠΎΠ΄ΠΎΠΌ!
h) ΠΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΠ΅
- AsNoTracking() Π΄Π»Ρ ΡΡΠ΅Π½ΠΈΡ Π΄Π°Π½Π½ΡΡ
Π±Π΅Π· ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ β ΠΌΠ΅Π½ΡΡΠ΅ ΠΏΠ°ΠΌΡΡΠΈ ΠΈ Π±ΡΡΡΡΠ΅Π΅.
var users = context.Users.AsNoTracking().Where(u => u.IsActive).ToList();
- ΠΠ°Π²Π΅ΡΠ·Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ: Π΅ΡΠ»ΠΈ ΠΏΠΎΡΠΎΠΌ ΠΏΡΡΠ°Π΅ΡΡΡΡ ΠΎΠ±Π½ΠΎΠ²ΠΈΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ, Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ½ΠΈΡΡ, ΡΡΠΎ ΠΎΠ½ΠΈ Β«detachedΒ».
i) ΠΠ°ΠΊΠ΅ΡΠ½Π°Ρ Π²ΡΡΠ°Π²ΠΊΠ°/ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅
- EF Core ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ Π΄Π΅Π»Π°Π΅Ρ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠ΅
INSERT
/UPDATE
Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ°.
- ΠΠ»Ρ Π±ΠΎΠ»ΡΡΠΈΡ
Π½Π°Π±ΠΎΡΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ BulkExtensions ΠΈΠ»ΠΈ Dapper.
context.BulkInsert(users); // ΡΠ΅ΡΠ΅Π· ΡΡΠΎΡΠΎΠ½Π½ΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ
- ΠΠ°Π²Π΅ΡΠ·Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ: ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΉ EF Core ΠΏΡΠΈ ΠΌΠ°ΡΡΠΎΠ²ΡΡ
ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡΡ
ΡΠΈΠ»ΡΠ½ΠΎ ΠΌΠ΅Π΄Π»Π΅Π½Π½Π΅Π΅ ADO.NET.
j) ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈΠ½Π΄Π΅ΠΊΡΠΎΠ² ΠΈ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ SQL
- EF Core ΡΠ°ΠΌ Π½Π΅ ΡΠΎΠ·Π΄Π°ΡΡ ΠΎΠΏΡΠΈΠΌΠ°Π»ΡΠ½ΡΠ΅ ΠΈΠ½Π΄Π΅ΠΊΡΡ.
- ΠΠ°ΠΆΠ½ΠΎ: Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ SQL ΡΠ΅ΡΠ΅Π·
context.Database.Log
ΠΈΠ»ΠΈ ToQueryString()
.
var sql = context.Users.Where(u => u.IsActive).ToQueryString();
Console.WriteLine(sql);
- ΠΠ°Π²Π΅ΡΠ·Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ: ORM ΠΈΠ½ΠΎΠ³Π΄Π° Π΄Π΅Π»Π°Π΅Ρ JOIN-Ρ ΠΈ ΠΏΠΎΠ΄Π·Π°ΠΏΡΠΎΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π΅ Π½ΡΠΆΠ½Ρ β ΠΏΡΠΎΡΠΈΠ»ΠΈΡΡΠΉ SQL Π²ΡΠ΅Π³Π΄Π°.
k) ΠΡΠΈΠ½Ρ
ΡΠΎΠ½Π½ΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ
- ΠΠ»Ρ Web API ΠΈ UI ΠΏΠΎΡΠΎΠΊΠΎΠ² Π»ΡΡΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
async/await
.
var users = await context.Users.Where(u => u.IsActive).ToListAsync();
- ΠΠ°Π²Π΅ΡΠ·Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ: Π°ΡΠΈΠ½Ρ
ΡΠΎΠ½Π½ΠΎΡΡΡ Π½Π΅ ΡΡΠΊΠΎΡΡΠ΅Ρ SQL, Π½ΠΎ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅Ρ ΠΏΠΎΡΠΎΠΊ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ.
l) ΠΠΈΠ½ΠΈΠΌΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠΉ
- ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
using var context = new DbContext();
ΠΈΠ»ΠΈ DI-ΡΠΈΠ½Π³Π»ΡΠΎΠ½.
- ΠΠ°Π²Π΅ΡΠ·Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ: Π΄Π΅ΡΠΆΠ°ΡΡ DbContext ΡΠ»ΠΈΡΠΊΠΎΠΌ Π΄ΠΎΠ»Π³ΠΎ β Π½Π°ΠΊΠΎΠΏΠ»Π΅Π½ΠΈΠ΅ ΡΡΠ΅ΠΊΠΈΠ½Π³Π° ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ², ΡΡΠ΅ΡΠΊΠΈ ΠΏΠ°ΠΌΡΡΠΈ.
β¬ ΠΠ΅ΡΠ½ΡΡΡΡΡ ΠΊ Π³Π»Π°Π²Π½ΠΎΠΉ
β¨Dvurechenskyβ¨