Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何首先在Entity Framework 6代码中创建多个1:1外键关系?_C#_Entity Framework_Ef Code First_Entity Framework 6_One To One - Fatal编程技术网

C# 如何首先在Entity Framework 6代码中创建多个1:1外键关系?

C# 如何首先在Entity Framework 6代码中创建多个1:1外键关系?,c#,entity-framework,ef-code-first,entity-framework-6,one-to-one,C#,Entity Framework,Ef Code First,Entity Framework 6,One To One,让我们假设我有三个表,每个表都有一个名为Id的主键: TableA ------ Id TableB ------ Id TableC ----- Id 目的是让这些实体中的每一个彼此具有一对一的导航属性,以便我可以在给定任何实体的任何方向上导航。不幸的是,我没有找到允许每个实体多次使用的[Key]、[ForeignKey]和导航属性的组合 例如,这是可行的(实体框架认为TableA是1:1关系中的主体): 但这不起作用: public class TableB { [Key]

让我们假设我有三个表,每个表都有一个名为
Id
的主键:

TableA
------
Id

TableB
------
Id

TableC
-----
Id
目的是让这些实体中的每一个彼此具有一对一的导航属性,以便我可以在给定任何实体的任何方向上导航。不幸的是,我没有找到允许每个实体多次使用的
[Key]
[ForeignKey]
和导航属性的组合

例如,这是可行的(实体框架认为
TableA
是1:1关系中的主体):

但这不起作用:

public class TableB
{
    [Key]
    [ForeignKey("TableA,TableC")] // The constructor documentation says this will work, but at runtime it throws an exception
    [Required]
    public Guid Id { get; set; }

    public virtual TableA TableA { get; set; }

    public virtual TableC TableC { get; set; }
}
这也不是:

public class TableB
{
    [Key]
    [Required]
    public Guid Id { get; set; }

    [ForeignKey("Id")]
    public virtual TableA TableA { get; set; }

    [ForeignKey("Id")]
    public virtual TableC TableC { get; set; }
}

如何使用属性来允许这些关系?目前,如果我想从
TableB
导航到
TableC
,我必须在
TableA
中导航,这会导致额外的不必要的数据库查找。实体框架似乎想要在可能没有层次关系的地方强制建立层次关系。

我认为您需要的是这样一个模型:

public class TableA
{
    [Key]
    public Guid Id { get; set; }

    public virtual TableB TableB { get; set; }
    public virtual TableC TableC { get; set; }
}
public class TableB
{
    [Key]
    [ForeignKey("TableA")]
    public Guid Id { get; set; }

    public virtual TableA TableA { get; set; }

    public virtual TableC TableC { get; set; }
}

public class TableC
{
    [Key]
    [ForeignKey("TableB")]
    public Guid Id { get; set; }

    public virtual TableB TableB { get; set; }

    [Required]
    public virtual TableA TableA { get; set; }
}
您不需要在
TableB
实体中为
TableC
导航属性指定FK属性,因为
TableB
是B和C之间关系的主体

更新 尝试删除
Required
数据注释并以这种方式配置关系,覆盖上下文中的
OnModelCreating
方法:

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
        modelBuilder.Entity<TableA>().HasOptional(a => a.TableC).WithOptionalPrincipal(c => c.TableA);

        base.OnModelCreating(modelBuilder);
  }
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity();
基于模型创建(modelBuilder);
}

不幸的是,由于导航属性()上的
[必需]
存在错误,我无法使用您的解决方案;但是,我怀疑它会起作用,因为
[Required]
建立了关系的主体。这就是为什么在我的示例中,我一直在使用
[ForeignKey]
。在微软合并拉请求之前,我似乎被额外的遍历卡住了。不过,我会将您的答案标记为已接受,因为如果没有bug,我怀疑它会起作用。您好@NathanAldenSr,我看不出会向您抛出什么异常,但无论如何,我会用另一种可能的解决方案更新我的答案,希望这有助于您总结错误:尝试保存从数据库加载但未检查其所有
[Required]
导航属性的实体将引发一个例外,即导航属性是必需的。这是因为导航属性是延迟加载的,所以在不点击属性的get访问器的情况下,
[必需]
注释认为值为
null
。您是否尝试了我在更新中共享的配置?它允许您将关系的两端配置为可选。我将尝试一下,谢谢。我通常会尽量避免在模型创建时覆盖
,而代之以属性,但在这种情况下,我可能没有选择:
  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
        modelBuilder.Entity<TableA>().HasOptional(a => a.TableC).WithOptionalPrincipal(c => c.TableA);

        base.OnModelCreating(modelBuilder);
  }