Entity Framework 代码优先初始化外键
Entity Framework Code First initializing foreign keys
代码如下所示:
public class Family
{
public int FamilyID { get; set; }
public virtual ICollection<Member> FamilyMembers { get; set; }
}
public class Member
{
public int MemberID { get; set; }
public virtual Family Family { get; set; }
}
public class Bicycle
{
public int BicycleID { get; set; }
public virtual Member Owner { get; set; }
}
public class MyContext : DbContext
{
public MyContext : base () { }
}
所以,Member和Bicycle是一对一的关系,Family和Member是一对多的关系。
我的问题是:如何使用上下文初始化这些外键?网上的教程都是说怎么定义,现在怎么初始化。我是简单地为它们分配一个正确的 int 值还是为它们分配一个完整的对象,如果是这样,我该怎么做?使用 LINQ?
@编辑:
假设有 2 个家庭:Smith 和 Johnson。 Smith 有 3 个成员:Ben、Amy、Brian。约翰逊有 2 名成员:约翰和娜塔莉。如何在我的代码中初始化所有这些?
您不需要在 Family 和 Member 之间明确定义外键。如果您需要,Entity Framework 会为您处理。因为你已经说过了属性
public virtual ICollection<Member> FamilyMembers { get; set; }
在 Family class 上,外键是在初始添加迁移或更新数据库期间创建的。所以你不需要 属性
public virtual FamilyFK { get; set; }
首先,解决这个问题:
public class Member
{
public int MemberID { get; set; }
public virtual Family Family { get; set; }
}
这应该足以配置关系。 EF 将按照约定使密钥标识。
您可以通过多种方式分配关系。如果将 FK ID 添加到模型中,则可以显式设置 FK ID,或者可以像这样使用导航属性:
var family = new Family { LastName = "Smith", ...};
List<Member> members = new List<Member>
{
new Member(){ Name = "Ben", ... },
new Member(){ Name = "Amy", ... },
new Member(){ Name = "Brian", ... }
};
family.FamilyMembers = members;
context.Family.Add(family);
context.SaveChanges();
要将自行车分配给车主:
var owner = context.Members.Find(ownerId);
var bike = new Bicycle
{
Make = "ACME",
Model = "XXXX",
Owner = owner
};
context.Bicycles.Add(bike);
context.SaveChanges();
编辑:是的,将 FK 添加到您的模型中当然是允许的。这就是我使用的方法。喜欢这个代码:
public class Member
{
public int MemberID { get; set; }
public int FamilyID { get; set; } // EF will automatically make this a FK by convention
public virtual Family Family { get; set; }
}
如果您不遵守约定或出于文档目的需要添加注释,则需要添加注释:
public class Member
{
public int MemberID { get; set; }
public int FamilyID { get; set; }
[ForeignKey("FamilyID")]
public virtual Family Family { get; set; }
}
我更喜欢流利的api。它使我的模型更清洁并分离关注点。对于简单的项目,您可以在您的上下文中的 OnModelCreating() 覆盖中添加所有流畅的代码,但我更喜欢将我的实体配置存储在我的上下文下的一个文件夹中(每个实体一个文件),如下所述:http://odetocode.com/blogs/scott/archive/2011/11/28/composing-entity-framework-fluent-configurations.aspx
您实际上可以使用此处描述的技术让 EF 自动找到您的流畅代码:https://msdn.microsoft.com/en-us/magazine/dn519921.aspx
关于子集合,是的,您可以在构造函数中对其进行 new:
public class Family
{
public Family()
{
FamilyMembers = new HashSet<Member>();
}
public int FamilyID { get; set; }
public virtual ICollection<Member> FamilyMembers { get; set; }
}
代码如下所示:
public class Family
{
public int FamilyID { get; set; }
public virtual ICollection<Member> FamilyMembers { get; set; }
}
public class Member
{
public int MemberID { get; set; }
public virtual Family Family { get; set; }
}
public class Bicycle
{
public int BicycleID { get; set; }
public virtual Member Owner { get; set; }
}
public class MyContext : DbContext
{
public MyContext : base () { }
}
所以,Member和Bicycle是一对一的关系,Family和Member是一对多的关系。 我的问题是:如何使用上下文初始化这些外键?网上的教程都是说怎么定义,现在怎么初始化。我是简单地为它们分配一个正确的 int 值还是为它们分配一个完整的对象,如果是这样,我该怎么做?使用 LINQ?
@编辑: 假设有 2 个家庭:Smith 和 Johnson。 Smith 有 3 个成员:Ben、Amy、Brian。约翰逊有 2 名成员:约翰和娜塔莉。如何在我的代码中初始化所有这些?
您不需要在 Family 和 Member 之间明确定义外键。如果您需要,Entity Framework 会为您处理。因为你已经说过了属性
public virtual ICollection<Member> FamilyMembers { get; set; }
在 Family class 上,外键是在初始添加迁移或更新数据库期间创建的。所以你不需要 属性
public virtual FamilyFK { get; set; }
首先,解决这个问题:
public class Member
{
public int MemberID { get; set; }
public virtual Family Family { get; set; }
}
这应该足以配置关系。 EF 将按照约定使密钥标识。
您可以通过多种方式分配关系。如果将 FK ID 添加到模型中,则可以显式设置 FK ID,或者可以像这样使用导航属性:
var family = new Family { LastName = "Smith", ...};
List<Member> members = new List<Member>
{
new Member(){ Name = "Ben", ... },
new Member(){ Name = "Amy", ... },
new Member(){ Name = "Brian", ... }
};
family.FamilyMembers = members;
context.Family.Add(family);
context.SaveChanges();
要将自行车分配给车主:
var owner = context.Members.Find(ownerId);
var bike = new Bicycle
{
Make = "ACME",
Model = "XXXX",
Owner = owner
};
context.Bicycles.Add(bike);
context.SaveChanges();
编辑:是的,将 FK 添加到您的模型中当然是允许的。这就是我使用的方法。喜欢这个代码:
public class Member
{
public int MemberID { get; set; }
public int FamilyID { get; set; } // EF will automatically make this a FK by convention
public virtual Family Family { get; set; }
}
如果您不遵守约定或出于文档目的需要添加注释,则需要添加注释:
public class Member
{
public int MemberID { get; set; }
public int FamilyID { get; set; }
[ForeignKey("FamilyID")]
public virtual Family Family { get; set; }
}
我更喜欢流利的api。它使我的模型更清洁并分离关注点。对于简单的项目,您可以在您的上下文中的 OnModelCreating() 覆盖中添加所有流畅的代码,但我更喜欢将我的实体配置存储在我的上下文下的一个文件夹中(每个实体一个文件),如下所述:http://odetocode.com/blogs/scott/archive/2011/11/28/composing-entity-framework-fluent-configurations.aspx
您实际上可以使用此处描述的技术让 EF 自动找到您的流畅代码:https://msdn.microsoft.com/en-us/magazine/dn519921.aspx
关于子集合,是的,您可以在构造函数中对其进行 new:
public class Family
{
public Family()
{
FamilyMembers = new HashSet<Member>();
}
public int FamilyID { get; set; }
public virtual ICollection<Member> FamilyMembers { get; set; }
}