将数据播种到数据库 table :如何在 OnModelCreating() 中配置 FK?

Seeding data to db table : How to configure FK in OnModelCreating()?

我正在通过 EF 迁移将数据播种到 SQL table。使用 OnModelCreating。 Table 我正在播种数据,对其他 table 有 FK。我如何在 OnModelCreating 中配置它?

  modelBuilder.Entity<UserEntity>().HasData(
                new UserEntity
                {
                    Id = Guid.NewGuid(),
                    CreatedAt = DateTime.Now,
                    CreatedBy = Guid.Empty,
                    Email = "jake@cart.er",
                    FirstName = "Jake",
                    LastName = "Carter"
                    
                }
            );

这些属性不是 FK。 还有一个 属性 - PreferenceIndicatorId,这是 FK。 我如何将其放入 OnModelCreating?

更新: 我尝试创建 PreferenceIndicator 对象并在 HasData() 中设置 PrefenrenceIndicator,但在添加迁移后,Up() 和 Down() 方法为空。

modelBuilder.Entity<UserEntity>().HasData(
                new UserEntity
                {
                    Id = Guid.NewGuid(),
                    CreatedAt = DateTime.Now,
                    CreatedBy = Guid.Empty,
                    Email = "jake@cart.er",
                    FirstName = "Jake",
                    LastName = "Carter",
                    PreferenceIndicator = preferenceIndicator
                }
            );

您的 PreferenceIndicator 是否已经存在?

或者您正在创建一个新的?

一般。

如果您的 PreferenceIndicator(相关对象)为“pre-EXIST”,那么您可以设置

UserEntity.PreferenceIndicatorId 到这个已知值。

此处的一个很好的比喻是“添加员工”功能。

大多数时候,当您添加新员工时,您的 Employee.DepartmentKey 将来自已创建的行。

因此您可以将 Employee 实体的 DepartmentKey 设置为精确值。

Employee emp = new Employee();

emp.DepartmentKey = 333; /* 333 already exists in the database/dept-table */

.....

如果你的关系对象不是“pre-exist”。

这当然是比较棘手的情况。

此处您不会设置 foreign-key SCALAR(在您的示例中为 UserEntity.PreferenceIndicatorId,在我的示例中为 Employee.DepartmentKey)。这是有道理的,你不能设置 FK SCALAR 值,因为它还不存在。

您需要编写 NAVIGATION OBJECTS/PROPERTIES 代码并允许 EF 为您完成工作。

但是,您还需要设置倒数。

例如:

public class Department
{


    public Department()
    {
        this.Employees = new List<Employee>();
    }


    public long DepartmentKey { get; set; }

    public ICollection<Employee> Employees { get; set; }

public class Employee
{

    public long EmployeeKey { get; set; }

public long MyParentDepartmentKey { get; set; } /* the scalar FK value */


    public Department MyParentDepartment { get; set; } /* the full object */

..

请注意,部门与员工有 1:N 关系。 (无论是 1:1、1:N 还是 M:N 都不是这里的主要关注点,但是您需要编写事物的“互惠”方面的代码。

同样下面的代码是关于部门没有“pre-exist”

Department dept = new Department();


Employee emp1 = new Employee();
emp1.MyParentDepartment = dept;


// and now what is often overlooked, the RECIPROCAL relationship

dept.Employees.Add(emp1);

现在你可以做类似的事情

myDbContext.Departments.Add(dept);
myDbConext.SaveAsync(CancellationToken.None); << you should NOT use 
.None here in your real code.

请记住,部门为员工 (S) 设置了导航 属性...而且,您在该部门的员工也设置了 MyParentDepartment。

注意,设置了导航 属性 OBJECTS,并且设置了 FK-SCALARS 的 none(因为它们还不知道)(MyParentDepartmentKey 作为这里的主要示例)。

调用 .SaveAsync 后,您应该查看 myDbContext 中的对象....您应该会看到水化的 Primary-Keys 和一个 FK。

简而言之,当他们pre-exist时设置导航标量。 当它们不 pre-exist.

时,设置导航 object/properties(和 RECIPROCATE 这些对象)

请注意,我的部门和员工代码假设(并且不会工作,除非)您已经设置了 属性 ORM 映射代码。不是《魔仙尘》

参见:

https://www.learnentityframeworkcore.com/configuration/one-to-many-relationship-configuration

个人提示:

如果您停止为 Type/PropertyName 使用不明确的名称,您将更好地学习 EF。

而不是

public Employee

   public Department Department {get; set;}

这就是我使用

的原因
public Employee

   public Department MyParentDepartment {get; set;}

甚至

public Employee

   public Department TheDepartment {get; set;}

或任何可以消除歧义的东西。

......

您还可以在示例中看到此“水合对象,而不是标量”:

https://www.learnentityframeworkcore.com/dbcontext/adding-data

在标有“添加多条记录”的部分(接近页面末尾)

代码:

var context = new SampleContext();
var author = new Author { FirstName = "Stephen", LastName = "King" };
var books = new List<Book> {
    new Book { Title = "It", Author = author },
    new Book { Title = "Carrie", Author = author },
    new Book { Title = "Misery", Author = author }
};
context.AddRange(books);
context.SaveChanges();

没有设置“主键”或“外键”值。但是 Book.Author 导航 属性 是由小写的“作者”设置的。

执行 .SaveChanges 后..(当然没有例外)...如果您查看对象...您会看到 PrimaryKey 和 ForeignKeySCALARS 被水化了