首页 > 解决方案 > 实体框架核心在 OnModelCreating 中分配外键约束?

问题描述

我试图弄清楚如何使用 Entity Framework Core 以编程方式生成我的数据库,并且在将外键分配给表中的字段时遇到了问题。我需要字段地址来引用地址对象并在我从数据库中检索记录时加载它。如果我使用创建数据库EnsureCreated,它会正确创建表,除了字段 AddressId 不是 Address 表的外键。我已经尝试对此进行研究,并遇到了这篇文章,它使用了一种名为 的方法HasForeignKey,但是从 Entity() 返回的任何内容都不知道HasForeignKey。如果我尝试手动输入它,我会收到此错误:

错误 CS1061“EntityTypeBuilder”不包含“HasForeignKey”的定义,并且找不到接受“EntityTypeBuilder”类型的第一个参数的扩展方法“HasForeignKey”(您是否缺少 using 指令或程序集引用?)

所以显然这种方法是无效的。我尝试遵循此文档,但我并不真正了解它在做什么以及如何将其应用于我的情况。在他们的例子中,他们有几个表、博客和帖子,其中博客有很多帖子,而帖子有一个博客。我尝试尽我所能,但我并不真正理解所有的行话以及它正在完成的工作。

如何简单地将 AddressId 中的值作为外键分配给 Addresses 中的记录?这是我正在使用的代码。

public class Person
    {
        [Key]
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public byte Age { get; set; }
        public int AddressId { get; set; }
        public Address Address { get; set; }
    }

    public class Address
    {
        [Key]
        public int Id { get; set; }
        public string Street { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
    }

    public class MyContext: DbContext
    {
        public DbSet<Person> People { get; set; }
        public DbSet<Address> Addresses { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite($"Data Source=test.db");
        }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.Entity<Address>().HasKey(v => v.Id);
            builder.Entity<Person>().HasKey(v => v.Id);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var db = new MyContext())
            {
                //var person = db.People.Find(1);

                db.Database.EnsureCreated();

                var person = new Person()
                {
                    FirstName = "Jack",
                    LastName = "Jackson",
                    Age = 50,
                    Address = new Address()
                    {
                        Street = "123 Street St",
                        City = "Jacksonville",
                        State = "Mississippi",
                        ZipCode = "00000-0000"
                    }
                };

                db.People.Add(person);

                db.SaveChanges();
            }
        }
    }

一点额外的信息:

标签: c#.net-coreentity-framework-coreef-fluent-api

解决方案


在您的 OnModelCreating 方法中,尝试将以下行更新为如下所示(我无法测试此代码,因此我的格式可能已关闭):

builder.Entity<Person>().HasOne(v => v.Address).WithMany().HasForeignKey(v => v.AddressId);

我相信,由于您在两个实体中都有 [Key] Data 注释,因此您无需通过 Fluent API 设置密钥。警告 - 我对 EF Core 也有点陌生,所以我可能是错的。:)


推荐阅读