19

可能重复:
代码优先:独立关联与外键关联?

在 EF 4 或 EF 5 Code First 中,什么是“独立关联”,什么是“外键关联”,如MSDN外键与独立关系中使用的那样 - 实体框架 5 是否有改进?(重点补充):

2.4.1 使用外键关联降低视图生成成本

我们已经看到了许多将模型中的关联从独立关联切换到外键关联的案例, 极大地改善了视图生成所花费的时间。

所以 - 现在我知道该使用哪个了。要是我知道它们是什么以及如何转换成它就好了!那么,我的问题是,您将如何定义这些术语?什么流利/注释/约定调用每个?

4

2 回答 2

36

只是我对为什么使用独立或外键关联的看法:

独立协会

优点:

  • 这是进入面向对象世界的正确方法。在面向对象的世界中,我们在聚合中使用引用,而不是一些魔术键。

缺点:

  • 使用纯 POCO,您不知道主体关系是否真的为 NULL 或只是未加载,因为在这两种情况下您的引用都是空的。您必须要求上下文在这两个空值之间有所不同。这对于重型基础实体来说不是问题,EntityObject其中每个到主体实体的导航属性都与另一个后缀为后缀的属性配对,以Reference提供有关关系的一些额外细节。
  • EF 管理独立关联的方法非常复杂,尤其是在附加分离的对象图时。每个独立的协会都有自己的状态,它永远不可能处于Modified状态。每个修改总是包括将旧关系设置为已删除并创建新关系作为添加 - 当您尝试使用它时,这真是一团糟。
  • 据报道,独立关联在 EF 初始化期间(或在视图预生成期间)显着减慢了视图生成。
  • 在您只需要绑定外键的数据绑定场景中,独立关联可能更难使用。

外键关联

优点:

  • 简单的。关键属性易于管理,它们解决了独立关联的所有问题 - 没有外部关联的状态、直接数据绑定、如果存在关系则立即可见(关键不为空)等。

缺点:

  • 它们在概念上是错误的,在 EF 中提供它们是从对象世界到关系世界的一大步。我仍然相信正确的解决方案正在改进或改变处理独立关联的方式,即使它可能导致 EFv1 和 EFv4 之间发生巨大的破坏性变化。我也不喜欢当前的情况,即我们有两种行为完全不同的关联。应该只有一种类型具有明确定义的行为和在实体上公开的可选外键属性。

这种差异仅对一对多关联很重要,因为一对一始终是外键关联,而多对多始终是独立关联。

于 2012-09-26T19:57:19.083 回答
28

外键关联是除了相应的导航属性之外,您的模型中还有一个外键属性。独立关联是当您的数据库中有一个外键列但与该列对应的外键属性不在您的模型中 - 即您有一个 NavigationProperty 但没有外键属性可以告诉您 ID 值是什么相关属性是没有实际进入相关属性的。

这是具有独立关联的模型示例(请注意,从属没有外键 - 只是导航属性):

public class Dependent
{
    public int Id { get; set; }

    [Required]
    public Principal PrincipalEntity { get; set; }

}

public class Principal
{
    public int Id { get; set; }
    public ICollection<Dependent> DependentEntities { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<Dependent> Dependents { get; set; }
    public DbSet<Principal> Principals { get; set; }
}

这是一个相同模型的示例,但具有 ForeignKey 关联(注意 PrincipalEntity_Id 属性和 [ForeignKey()] 属性):

public class Dependent
{
    public int Id { get; set; }

    public int PrincipalEntity_Id { get; set; }

    [Required]
    [ForeignKey("PrincipalEntity_Id")]
    public Principal PrincipalEntity { get; set; }

}

public class Principal
{
    public int Id { get; set; }
    public ICollection<Dependent> DependentEntities { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<Dependent> Dependents { get; set; }
    public DbSet<Principal> Principals { get; set; }
}

请注意,您的数据库不会更改 - 基础数据库始终具有外键列,但具有独立关联,它没有公开。

使用外键关联,您只需更改外键的值即可更新关系。如果您知道该值,这很方便,因为您不需要加载要将导航属性更新到的实体。

于 2012-09-26T18:07:35.587 回答