„Háttéralkalmazások/Záróvizsgatételek” változatai közötti eltérés
→4. EF Core: Tétel kidolgozása |
→4. EF: Tétel kidolgozása |
||
| 376. sor: | 376. sor: | ||
=== Mikor használjuk, és mikor nem? === | === Mikor használjuk, és mikor nem? === | ||
==== Mikor nem használjuk ==== | ==== Mikor nem használjuk ==== | ||
| 396. sor: | 395. sor: | ||
=== Mi a <code>DbContext</code>? === | === Mi a <code>DbContext</code>? === | ||
Egy EF Core-beli osztály, mely egy adatbázis-munkamenetet reprezentál. Általában a DAL-ban hozunk létre egy <code>DbContext</code>-ből leszármazó osztályt. | Egy EF Core-beli osztály, mely egy adatbázis-munkamenetet reprezentál. | ||
Általában a DAL-ban hozunk létre egy <code>DbContext</code>-ből leszármazó osztályt. Mivel a <code>DbContext</code> vezeti a nyilvántartást az entitáspéldányokról, azok felderítésében segíti, ha <code>DbSet<Entity></code> tagváltozókat is megadunk a DAL-osztályban. Egy <code>DbContextOptions</code> objektum átadásával – mely tartalmazza az adatbázis típusát és connection stringjét – lehet példányosítani. | |||
A service layernek DI-vel adjuk át a <code>DbContext</code>-et, és annak tagfüggvényeit meghívva lehet LINQ-ket futtatni. | A service layernek DI-vel adjuk át a <code>DbContext</code>-et, és annak tagfüggvényeit meghívva lehet LINQ-ket futtatni. | ||
| 448. sor: | 449. sor: | ||
=== Milyen két lehetőségünk van a modell konfigurációjára? === | === Milyen két lehetőségünk van a modell konfigurációjára? === | ||
==== Code first ==== | ==== Code first ==== | ||
{| class="wikitable" | {| class="wikitable" | ||
| 488. sor: | 488. sor: | ||
=== Hogy néz ki egy entitás, hogyan készítünk kapcsolatokat közöttük? === | === Hogy néz ki egy entitás, hogyan készítünk kapcsolatokat közöttük? === | ||
... | {| class="wikitable" | ||
! | |||
!1:N | |||
!N:N | |||
|- | |||
|annotációkkal | |||
|Entitások:<syntaxhighlight lang="csharp" line="1">public class Blog | |||
{ | |||
[Key] | |||
public int Id { get; set; } | |||
public string Title { get; set; } = null!; | |||
public List<Post> Posts { get; set; } = new(); | |||
} | |||
public class Post | |||
{ | |||
[Key] | |||
public int Id { get; set; } | |||
public string Content { get; set; } = null!; | |||
[ForeignKey(nameof(Blog))] | |||
public int BlogId { get; set; } | |||
public Blog Blog { get; set; } = null!; // parent navigation | |||
}</syntaxhighlight> | |||
|Entitások:<syntaxhighlight lang="csharp" line="1">public class Student | |||
{ | |||
[Key] | |||
public int Id { get; set; } | |||
public string Name { get; set; } = null!; | |||
public List<Enrollment> Enrollments { get; set; } = new(); | |||
} | |||
public class Course | |||
{ | |||
[Key] | |||
public int Id { get; set; } | |||
public string Title { get; set; } = null!; | |||
public List<Enrollment> Enrollments { get; set; } = new(); | |||
} | |||
public class Enrollment | |||
{ | |||
[ForeignKey(nameof(Student))] | |||
public int StudentId { get; set; } | |||
public Student Student { get; set; } = null!; | |||
[ForeignKey(nameof(Course))] | |||
public int CourseId { get; set; } | |||
public Course Course { get; set; } = null!; | |||
public DateTime EnrolledOn { get; set; } | |||
}</syntaxhighlight> | |||
|- | |||
|Fluent API-val | |||
|Entitások:<syntaxhighlight lang="csharp" line="1">public class Blog | |||
{ | |||
public int Id { get; set; } | |||
public string Title { get; set; } | |||
public List<Post> Posts { get; set; } = new(); | |||
} | |||
public class Post | |||
{ | |||
public int Id { get; set; } | |||
public string Content { get; set; } | |||
public int BlogId { get; set; } // foreign key | |||
public Blog Blog { get; set; } = null!; // parent navigation | |||
}</syntaxhighlight><code>DbContext</code>:<syntaxhighlight lang="csharp" line="1">protected override void OnModelCreating(ModelBuilder modelBuilder) | |||
{ | |||
modelBuilder.Entity<Blog>() | |||
.HasMany(b => b.Posts) | |||
.WithOne(p => p.Blog) | |||
.HasForeignKey(p => p.BlogId); | |||
}</syntaxhighlight> | |||
|Entitások:<syntaxhighlight lang="csharp" line="1">public class Student | |||
{ | |||
public int Id { get; set; } | |||
public string Name { get; set; } | |||
public List<Course> Courses { get; set; } = new(); | |||
} | |||
public class Course | |||
{ | |||
public int Id { get; set; } | |||
public string Title { get; set; } | |||
public List<Student> Students { get; set; } = new(); | |||
}</syntaxhighlight><code>DbContext</code>:<syntaxhighlight lang="csharp" line="1">protected override void OnModelCreating(ModelBuilder modelBuilder) | |||
{ | |||
modelBuilder.Entity<Student>() | |||
.HasMany(s => s.Courses) | |||
.WithMany(c => c.Students) | |||
.UsingEntity("StudentCourse"); | |||
}</syntaxhighlight>A kapcsolótáblát az EF automatikusan létrehozza. | |||
|} | |||
=== Hogyan készítünk lekérdezéseket, hogyan módosítunk adatokat EF Core-ban? === | === Hogyan készítünk lekérdezéseket, hogyan módosítunk adatokat EF Core-ban? === | ||
... | A <code>Dogs</code> entitás példáját véve: | ||
{| class="wikitable" | |||
|+lekérdezések | |||
!típus | |||
!<code>dbContext</code>-függvényhívás | |||
|- | |||
|'''összes találat''' | |||
|<code>.Any(d => !d.Ownerships.Any())</code> | |||
|- | |||
|számlálás | |||
|<code>.Any(…).Count()</code> | |||
|- | |||
|'''projekció''' | |||
|<code>.Select(d => d.Name)</code> | |||
|- | |||
|csoportos projekció és spread | |||
|<code>.SelectMany(d => d.Ownerships)</code> | |||
|- | |||
|'''szelekció''' | |||
|<code>.Where(d => d.Name == "Bodri")</code> | |||
vagy ID alapján: | |||
<code>.Find(dogId)</code> | |||
|- | |||
|egyetlen találat | |||
|<code>.Single(d => d.Name == "Bodri")</code> | |||
vagy | |||
<code>.SingleOrDefault(…)</code> | |||
|- | |||
|első találat | |||
|<code>.First(d => d.Name == "Bodri")</code> | |||
vagy | |||
<code>.FirstOrDefault(…)</code> | |||
|- | |||
|'''csoportosítás''' | |||
|<code>.GroupBy(d => d.Ownerships.Count())</code> | |||
|- | |||
|'''rendezés''' | |||
|<code>.OrderBy(d => d.Ownerships.Count())</code> | |||
<code>.ThenBy(d => d.BirthDate)</code> | |||
|- | |||
|lapozás | |||
|<code>.Skip(20)</code> | |||
és | |||
<code>.Take(10);</code> | |||
|} | |||
{| class="wikitable" | |||
|+módosítások | |||
!CRUD | |||
!<code>dbContext</code>-függvényhívás | |||
|- | |||
|create | |||
|<code>.Dogs.Add(newDog);</code> | |||
|- | |||
|read | |||
|ld. az előző táblázatot | |||
|- | |||
|update | |||
|<code>.Dogs.Find(dogId);</code> | |||
<code>dog.BirthDate = birthDate;</code> | |||
|- | |||
|delete | |||
|adatbetöltéssel: | |||
<code>.Dogs.Find(dogId);</code> | |||
<code>.Dogs.Remove(dog);</code> | |||
adatbetöltés nélkül: | |||
az előző táblázatból bármit meghívni az ''első találat'' sorig, majd utána <code>.ExecuteDelete();</code> | |||
|} | |||
...majd utána <code>dbContext.SaveChanges();</code>. | |||
== 5. JPA – általános == | == 5. JPA – általános == | ||