什么是独立协会和外国关键协会?

Sco*_*ord 18 c# entity-framework-4 entity-framework-5

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

在EF 4或EF 5 Code First中,什么是"独立关联"以及什么是MSDN外键与独立关系使用的"外键关联" - 实体框架5有哪些改进?(重点补充):

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

我们已经看到了一些案例,其中模型中的关联从独立关联切换到外键关联 大大改善了视图生成所花费的时间.

所以 - 现在我知道要使用哪个.只要我知道它们是什么以及如何转换成它!那么我的问题是,您如何定义这些条款?什么流利/注释/约定调用每个?

Lad*_*nka 36

关于为何使用独立或外国关键协会的意见:

独立协会

优点:

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

缺点:

  • 使用纯POCO,您不知道主关系是否真的为NULL或者只是没有加载,因为在这两种情况下您的引用都是null.您必须要求上下文在这两个空值之间有所不同.对于重EntityObject基础实体而言,这不是问题,其中每个到主体实体的导航属性与另一个后缀属性配对,Reference提供关于该关系的一些额外细节.
  • EF管理独立关联的方式非常复杂,特别是在附加分离对象图时.每个独立的协会都有自己的州,它永远不会处于Modified州.每次修改总是包括将旧关系设置为已删除并创建添加的新关系 - 当您尝试使用它时,这是一个真正的混乱.
  • 据报道,独立协会显着降低了EF初始化期间(或视图预生成期间)的视图生成速度.
  • 在需要仅绑定外键的数据绑定方案中,独立关联可能更难使用.

外国关键协会

优点:

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

缺点:

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

这种差异仅适用于一对多关联,因为一对一总是外键关联,而多对多总是独立关联.

  • 最后一句话+1.这对我来说并不明显. (6认同)

Paw*_*wel 27

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

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

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; }
}
Run Code Online (Sandbox Code Playgroud)

这里是同一型号的,但随着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; }
}
Run Code Online (Sandbox Code Playgroud)

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

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