.net Core / Bez kategorii / c# / Entity Framework

EntityFramework Core 2.1 – relacja jeden do jednego, czyli jak zrobić żeby było ładnie

Cóż to był za dzień.
Tabela użytkowników:

Id
Login
FirstName
LastName
...

Tabela innych obiektów np.: samochodów służbowych zawierających referencję do tabeli użytkowników z informacją, kto posiada jaki samochód. Relacja jeden do jednego, no bo, w której firmie ma się dwa samochody służbowe. Ja nie znam, a na potrzeby posta jest to przykład doskonały.
Wykorzystanie EF Core w podejściu Code First. No i chciałbym aby to w tabeli samochodów była referencja do użytkownika, a tabela użytkownika ma nic nie wiedzieć o samochodzie. Poza tym chcę mieć w kodzie C# zmienną typu referencyjnego do typu samochodu.
Ósme poty, a może nawet dziewiąte, ale udało mi się uzyskać pożądany efekt. W tabeli samochodów jest pole UserId, a EF Core nie generuje mi dodatkowego pola UserId1, za to w tabeli użytkowników nie ma nic na temat samochodu. Jak to zrobiłem?

Klasa User

public class ApplicationUser
{
	[Key]
	public int Id { get; set; }
	public string Login { get; set; }
	public DateTime CreationDate { get; set; }
	public string FirstName { get; set; }
	public string LastName { get; set; }
	public bool IsActive { get; set; }
	public bool IsDeleted { get; set; }
	[ForeignKey("CreatedBy")]
	public int CreatedById { get; set; }
	public virtual ApplicationUser CreatedBy { get; set; }
}

Klasa Car

public class Car
{
	[Key]
	public int Id { get; set; }
	[ForeignKey("ApplicationUser")]
	public int AppcalitionUserId { get; set; }
	public virtual ApplicationUser ApplicationUser { get; set; }
}  

Następnie konfiguracja w klasie ApplicationDbContext:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
	base.OnModelCreating(modelBuilder);
	modelBuilder.Entity<ApplicationUser>().ToTable("Users");
	modelBuilder.Entity<ApplicationUser>().Property(x => x.Id).ValueGeneratedOnAdd();
	modelBuilder.Entity<ApplicationUser>().HasMany<ApplicationUser>().WithOne(x => x.CreatedBy).OnDelete(DeleteBehavior.Restrict);
	
	modelBuilder.Entity<Car>().ToTable("Cars");
	modelBuilder.Entity<Car>().Property(x => x.Id).ValueGeneratedOnAdd();    
	modelBuilder.Entity<Car>().HasOne(x => x.ApplicationUser).WithOne().HasForeignKey<Car>(x => x.AppcalitionUserId);
}        

I, VOILA, gotowe.

Ale żeby nie było tak pięknie to Lazy Loading, który w wersji 2.1, a i owszem, już jest obecny, należy doinstalować poprzez dorzucenie pakietu do projektu: Microsoft.EntityFrameworkCore.Proxies, a następnie w Startup.cs dodać linijkę w konfiguracji usługi:

services.AddDbContext<ApplicationDbContext>(options => 
	options
		.UseLazyLoadingProxies()
		.UseSqlServer(   Configuration.GetConnectionString("DefaultConnection")
));

I teraz wszystko pięknie działa, czyli ApplicationUser jest wypełniana na żądanie, a ja biorę się do dalszej roboty.

Leave a Reply

Your email address will not be published. Required fields are marked *