Table per Type in Entity Framework Core 2.0

限于喜欢 提交于 2020-01-23 03:08:18

问题


These are my models:

public class Company
{
   public int CompanyId { get; set; }
   public string Name { get; set; }
   public string Address { get; set; }
   public string Email { get; set; }
   public string Url { get; set; }
   //...
}

public class HeadOffice : Company
{
   public int HeadOfficeId { get; set; }
   public virtual List<BranchOffice> BranchOffice { get; set; } = new List<BranchOffice>();
}

public class BranchOffice : Company
{
   public int BranchOfficeId { get; set; }
   public virtual HeadOffice HeadOffice { get; set; }
}

I wanted the following database structure:

Table Company

  • CompanyId (PK)
  • Name
  • Address
  • Email
  • Url

Table HeadOffice

  • HeadOfficeId (PK)
  • CompanyId (FK)

Table BranchOffice

  • BranchOfficeId (PK)
  • HeadOfficeId (FK)
  • CompanyId (FK)

How can I do this?

When I create this migration, the EF creates just one table, with all columns! I don't want this approach!


回答1:


You would have to change your Model to look like this, note that you can't use inheritance using this approach:

public class Company
{
   public int CompanyId { get; set; }
   //...
}

public class Company
{
   public int CompanyId { get; set; }
   public string Name { get; set; }
   //...
}

public class HeadOffice
{
   [ForeignKey(nameof(Company))]
   public int CompanyId { get; set; }
   public Company Company { get; set; }
   // Add Properties here
}

public class BranchOffice
{
   [ForeignKey(nameof(Company))]
   public int CompanyId { get; set; }
   public Company Company { get; set; }
   // Add Properties here
}

Your DbContext:

public class YourContext : DbContext
{
  public DbSet<Company> Companys { get; set; }
  public DbSet<HeadOffice> HeadOffices { get; set; }
  public DbSet<BranchOffice> BranchOffices { get; set; }

  public YourContext(DbContextOptions<YourContext> options)
    : base(options)
  {
  }
}

You could then use EF Core Migrations. The command would look somewhat like this:

dotnet ef migrations add Initial_TPT_Migration -p ./../../ModelProject.csproj -s ./../../ModelProject.csproj -c YourContext -o ./TptModel/CodeFirst/Migrations

It generats a Class Initial_TPT_Migration that contains methods to generate your database.

Usage

To query you would need to map Company Properties to the fieldnames. If you combine this with the Repository Pattern (link), it could actually be as convenient as the default approach in EF Core currently is to use.

YourContext ctx = ...

// Fetch all BranchOffices
var branchOffices = ctx.BranchOffices
          .Select(c => new BranchOffice()
                  {
                    CompanyId = c.CompanyId,
                    Name = c.Company.Name,
                  })
          .ToList();

You can find more informations about this approach here.




回答2:


You can find an answer here https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/inheritance?view=aspnetcore-2.1

Also check this topic out if you need many inherited classes against one table https://docs.microsoft.com/en-us/ef/core/modeling/relational/inheritance

Copying the code here just in case microsoft used to mess with urls and docs

  1. Each inherited type per table
public class SchoolContext : DbContext
{
    public SchoolContext(DbContextOptions<SchoolContext> options) : base(options)
    {
    }

    public DbSet<Student> Students { get; set; }
    public DbSet<Instructor> Instructors { get; set; }
    public DbSet<Person> People { get; set; }

    protected override void OnModelCreating(ModelBuilder b)
    {
        b.Entity<Student>().ToTable("Student");
        b.Entity<Instructor>().ToTable("Instructor");
        b.Entity<Person>().ToTable("Person");
    }
}

public abstract class Person
{
    public int ID { get; set; }

    public string LastName { get; set; }
    public string FirstMidName { get; set; }
}

public class Instructor : Person
{
    public DateTime HireDate { get; set; }
}

public class Student : Person
{
    public DateTime EnrollmentDate { get; set; }
}
  1. Many inherited types in one table
public class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .HasDiscriminator<string>("blog_type")
            .HasValue<Blog>("blog_base")
            .HasValue<RssBlog>("blog_rss");
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

public class RssBlog : Blog
{
    public string RssUrl { get; set; }
}


来源:https://stackoverflow.com/questions/47733184/table-per-type-in-entity-framework-core-2-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!