Внешний ключ для составного ключа? - PullRequest
0 голосов
/ 03 февраля 2020

Возможно ли в структуре сущностей иметь внешний ключ, указывающий на составной ключ?

Я нашел этот ответ , который научил меня, как это делать на SQL сервере. , но мне нужно сделать это в EF.

1 Ответ

1 голос
/ 04 февраля 2020

Да. Вот простой пример (это EF Core 3):

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.SqlClient;
using System.Linq;

namespace EfCore3Test
{

    public class Author
    {
        public int TenantId { get; set; }
        public int AuthorId { get; set; }
        public virtual ICollection<Book> Books { get; } = new HashSet<Book>();
    }

    public class Book
    {
        public int TenantId { get; set; }
        public int BookId { get; set; }
        public int AuthorId { get; set; }
        public Author Author { get; set; }
    }


    public class Db : DbContext
    {


        public DbSet<Author> Authors { get; set; }
        public DbSet<Book> Books { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Author>().HasKey(b => new { b.TenantId, b.AuthorId });

            modelBuilder.Entity<Book>().HasKey(b => new { b.TenantId, b.BookId });

            modelBuilder.Entity<Book>()
                .HasOne<Author>(b => b.Author)
                .WithMany(a => a.Books)
                .HasForeignKey( b => new { b.TenantId, b.AuthorId })
                .OnDelete(DeleteBehavior.Cascade);

            base.OnModelCreating(modelBuilder);
        }
        public static readonly ILoggerFactory MyLoggerFactory
            = LoggerFactory.Create(builder => { builder.AddConsole(); });
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer("Server=localhost;Database=EFCore3Test;Integrated Security = true", a => a.UseRelationalNulls(true))
                          .ConfigureWarnings(c => c.Log((RelationalEventId.CommandExecuting, LogLevel.Information)))
                          .UseLoggerFactory(MyLoggerFactory);
            base.OnConfiguring(optionsBuilder);
        }

    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var db = new Db())
            {

                db.Database.EnsureDeleted();
                db.Database.EnsureCreated();

            }


        }
    }
}

output

 CREATE TABLE [Authors] (
      [TenantId] int NOT NULL,
      [AuthorId] int NOT NULL,
      CONSTRAINT [PK_Authors] PRIMARY KEY ([TenantId], [AuthorId])
  );

  CREATE TABLE [Books] (
      [TenantId] int NOT NULL,
      [BookId] int NOT NULL,
      [AuthorId] int NOT NULL,
      CONSTRAINT [PK_Books] PRIMARY KEY ([TenantId], [BookId]),
      CONSTRAINT [FK_Books_Authors_TenantId_AuthorId] FOREIGN KEY ([TenantId], [AuthorId]) REFERENCES [Authors] ([TenantId], [AuthorId]) ON DELETE CASCADE
  );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...