0

我试图与客户一起在许可证表中创建复合键和外键,但是当我运行EF命令时update-database,会在许可证表中生成以下列。

在此处输入图像描述

我有以下表格

public class Company
{
   public int Id { get; set; }
   public string Name { get; set; }
   public virtual ICollection<Customer> Customers { get; set; }
}


 public class Customer
 {
     public int Id { get; set; }
     public string Name { get; set; }

     public int CompanyId { get; set; }
     public virtual Company Company { get; set; }

     public ICollection<License> Licenses{ get; set; }
  }


public class License
{
   public int Id { get; set; }
   public int Count { get; set; }

   public int CustomerId { get; set; }
   public virtual Customer Customer { get; set; }
}


public class MyDbContext : DbContext
{
    public MyDbContext() : base("TestConnection")
    {

    }
    public DbSet<Company> Company { get; set; }

    public DbSet<Customer> Customer { get; set; }

    public DbSet<License> License { get; set; }


    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Customer>()
            .HasKey(cust => new { cust.Id, cust.CompanyId })
            .Property(cust => cust.Id).HasColumnOrder(1)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        modelBuilder.Entity<Customer>()
            .Property(cust => cust.CompanyId).HasColumnOrder(2);



        modelBuilder.Entity<License>()
           .HasKey(lic => new { lic.Id, lic.CustomerId })
           .Property(lic => lic.Id).HasColumnOrder(1)
           .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        modelBuilder.Entity<License>()
            .Property(lic => lic.CustomerId).HasColumnOrder(2);



        base.OnModelCreating(modelBuilder);
    }
}

注意:我希望 CustomerId 在 License 表中充当 PK 和 FK,但不知道那些名为Customer_Id和 Customer_CompanyId` 的额外列是如何生成的。

4

1 回答 1

1

有几件事。客户有一个复合密钥,因此您需要许可证上有两个 FK 属性。并且您需要将 License.Customer 与 Customer.Licenses 相关联,否则可能是两个独立的关联。

此外,您应该将父键放在子实体的 PK 索引中。这样相关的行存储在一起,PK索引也支持外键关系。否则,您确实需要两个单独的索引:例如在 Customer(Id) 和 Customer(CompanyId) 上。如果您希望能够在没有公司的情况下在 Id 上查找客户,则在 Customer(id) 上添加索引。

此外,EF 将从用于声明键的匿名类型表达式派生键列顺序,因此您无需显式设置它。

所以像这样:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ef62test
{
    class Program
    {

        public class Company
        {
            public int Id { get; set; }
        }
        public class Customer
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int CompanyId { get; set; }
            public virtual Company Company { get; set; }

            public ICollection<License> Licenses { get; set; }
        }


        public class License
        {
            public int Id { get; set; }
            public int Count { get; set; }

            public int CompanyId { get; set; }
            public int CustomerId { get; set; }
            public virtual Customer Customer { get; set; }
        }


        public class MyDbContext : DbContext
        {

            public DbSet<Company> Company { get; set; }

            public DbSet<Customer> Customer { get; set; }

            public DbSet<License> License { get; set; }


            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Entity<Customer>()
                    .HasKey(cust => new { cust.CompanyId, cust.Id })
                    .Property(cust => cust.Id)
                    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);


                modelBuilder.Entity<License>()
                   .HasKey(lic => new { lic.CompanyId, lic.CustomerId, lic.Id })
                   .Property(lic => lic.Id)
                   .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

                modelBuilder.Entity<License>()
                    .HasRequired(l => l.Customer)
                    .WithMany(c => c.Licenses)
                    .HasForeignKey(l => new { l.CompanyId, l.CustomerId });

                base.OnModelCreating(modelBuilder);
            }
        }
        static void Main(string[] args)
        {
            Database.SetInitializer(new DropCreateDatabaseAlways<MyDbContext>());

            using (var db = new MyDbContext())
            {
                db.Database.Log = s => Console.WriteLine(s);

                db.Database.Initialize(true);



                db.SaveChanges();
            }


            Console.WriteLine("Hit any key to exit.");
            Console.ReadKey();
        }
    }
}
于 2018-07-19T20:30:55.940 回答