EF связь с несколькими внешними ключами в одной и той же таблице пользователей приложений с первичным ключом

#c# #entity-framework #entity-framework-6

Вопрос:

Я хочу создать отношение «один ко многим», используя EF 6, используя подход, основанный на первом коде.

Давайте возьмем простой и классический пример. У меня есть две сущности Invoice , UserApplication которые имеют отношение «один ко многим»:

Я также хочу иметь UpdatedById связь с той же ApplicationUser таблицей, чтобы иметь возможность отображать имена в пользовательском интерфейсе тех, кто добавил запись и кто ее изменил.

  public partial class ApplicationUser : IdentityUser
    {
     public string FirstName { get; set; };
     public string  LastName { get; set; };
    }
     public virtual List<Invoice> Invoices { get; set; }
    
    
    
    public class Invoice
    {
     public int Id { get; set; }
     public string Details { get; set; }
     public string CreatedById { get; set; }
     public string UpdatedById { get; set; }
    }
     public virtual ApplicationUser CreatedBy { get; set; }
    
     builder.Entity<Invoice>()
     .HasOne(f => f.CreatedBy)
     .WithMany(mu => mu.Invoices)
     .HasForeignKey(f => f.CreatedById);
 

Комментарии:

1. Ты забыл задать вопрос.

Ответ №1:

Если вам нужны свойства навигации пользователя приложения для этих отношений, вам потребуется создать и настроить отдельные свойства.

напр.

 using Microsoft.EntityFrameworkCore;
using System.Linq;
using System;
using System.Collections.Generic;

namespace EfCore6Test
{

    public partial class ApplicationUser //: IdentityUser
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public virtual ICollection<Invoice> InvoicesCreated { get; } = new HashSet<Invoice>();
        public virtual ICollection<Invoice> InvoicesLastUpdated { get; } = new HashSet<Invoice>();
    }
    
    public class Invoice
    {
        public int Id { get; set; }
        public string Details { get; set; }
        public int CreatedById { get; set; }
        public int UpdatedById { get; set; }
        public virtual ApplicationUser CreatedBy { get; set; }
        public virtual ApplicationUser LastUpdatdBy { get; set; }
    }
    
    public class Db: DbContext
    {
        public DbSet<Invoice> Invoices{ get; set; }
        public DbSet<ApplicationUser> Users{ get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Invoice>()
                        .HasOne(f => f.CreatedBy)
                        .WithMany(mu => mu.InvoicesCreated)
                        .HasForeignKey(f => f.CreatedById)
                        .OnDelete(DeleteBehavior.Restrict); 

            modelBuilder.Entity<Invoice>()
                        .HasOne(f => f.LastUpdatdBy)
                        .WithMany(mu => mu.InvoicesLastUpdated)
                        .HasForeignKey(f => f.UpdatedById)
                        .OnDelete(DeleteBehavior.Restrict);

            base.OnModelCreating(modelBuilder);
        }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer("Server=localhost;database=efCore6Test;Integrated Security=true;TrustServerCertificate=true", o => o.UseRelationalNulls(true))
                .LogTo(Console.WriteLine, Microsoft.Extensions.Logging.LogLevel.Information);
            base.OnConfiguring(optionsBuilder);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            {
                
                using var db = new Db();
                db.Database.EnsureDeleted();
                db.Database.EnsureCreated();
               

            }


        }
    }
}
 

Или просто опустите Свойства навигации для пользователя приложения.

Комментарии:

1. Я все еще не смог заставить это работать так, как я ожидал, если вас это не беспокоит, не могли бы вы, пожалуйста, привести краткий пример всего сценария. Спасибо.