我想确保我理解这一切。它似乎有效,但我担心所有这些设置都是通过读取我的代码的代码发生的,我希望魔法能起作用。 (如果重要的话,我使用 SQL Server 作为底层存储库。)
首先,当我有如下课程时:
public class User
{
public int Id { get; }
它将使列 Id 成为主键,在插入记录时自动填充它,并将其设置为在下一次插入时自动递增到下一个值。
二、当我PK时:FK如下:
public class State
{
public int Id { get; set; }
public IList<County> Counties { get; set; } = new List<County>();
}
public class County
{
public int Id { get; set; }
}
会在那里自动建立PK:FK关系。当它读入 State 对象时,它会读入所有关联的 County 对象并填充 Counties 列表。
第三,当我有很多用户,他们在各个县城旅行,所以每个用户有多个县城,每个县城有多个用户,我是这样设置的:
public class User
{
public int Id { get; }
public IList<County> Counties { get; set; } = new List<County>();
}
public class County
{
public int Id { get; set; }
}
它会再次将这一切连接起来,并在加载用户对象时填充 Counties 属性。
第四,如果我如下声明类会发生什么,因为这会导致主要递归:
public class User
{
public int Id { get; }
public IList<County> Counties { get; set; } = new List<County>();
}
public class County
{
public int Id { get; set; }
public IList<User> Users{ get; set; } = new List<User>();
}
第五,如果它按属性名称进行,它会理解用户与县(即“s”与“ies”)。命名处理有什么需要注意的吗?
EF Convention 将使用特定规则来制定关系。如果您使用代码优先,您将看到 EF 在表中创建外键列,它在实体内的幕后使用影子属性。
如果您有一个不符合这些规则的现有模式,或者想要改变行为,或者 EF 无法解决关系的情况,则出现属性或其他特定配置。
映射到现有模式时,EF 将从内存中查找以下 PK:Id、TableNameId 和 TableName_Id。当涉及到 FKs 时,它会查找 TableNameId 或 TableName_Id
所以在你的第二个例子中:
public class User
{
public int Id { get; }
public IList<County> Counties { get; set; } = new List<County>();
}
public class County
{
public int Id { get; set; }
}
EF 将在 County 表中查找 UserId 或 User_Id。如果运行 Code First,它将默认创建 User_Id。
注解真正发挥作用的地方是在对同一个表使用多个引用时。例如,如果您在县上有一个 CreatedBy 和 LastModifiedBy 用户引用:
public class County
{
public int Id { get; set; }
public User CreatedBy { get; set; }
public User LastModifiedBy { get; set; }
}
这就是事情变得有点不同的地方。您可能认为 EF 会期望/创建类似 CreatedBy_Id 和 LastModifiedBy_Id 的内容,但它实际上会创建 User_Id 和 User_Id1。 EF 的约定基于类型名称 而不是属性名称。
[ForeignKey("CreatedBy_Id")]
public User CreatedBy { get; set; }
[ForeignKey("LastModifiedBy_Id")]
public User LastModifiedBy { get; set; }
如果您出于任何原因想要在用户上拥有县集合,这也需要一些工作。您需要告诉 EF User.Counties 将引用该县的哪个(如果有)用户集合。否则你会想要像
这样的东西ICollection<County> CountiesICreated { get; set; }
ICollection<County> CountiesILastModified { get; set; }
并将这些显式映射到另一端的对应关系。
就我个人而言,我不喜欢依赖 EF 的关系约定,因为我几乎完全首先使用模式来处理现有数据库或负责组织整体模式的利益相关者 DBA。如有疑问,请明确说明,尤其是对于人际关系。