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.