Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.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
Entity framework EF CF-如何建立可选关系:可选关系?_Entity Framework_Ef Code First - Fatal编程技术网

Entity framework EF CF-如何建立可选关系:可选关系?

Entity framework EF CF-如何建立可选关系:可选关系?,entity-framework,ef-code-first,Entity Framework,Ef Code First,我希望Foo有一个可选的Bar和Bar有一个可选的Foo 我似乎设法让它工作,但我只在其中一个表上创建了一个额外的列,例如,它在SQL中只在其中一个表上创建了InvitationId,然后也在其中一个表上创建了InvitationId,尽管两个实体的设置方式相同,但设置方式相反 所以我想做一个更小的复制,这样我就可以问这个问题了,但是在这个过程中,虽然我刚刚复制了原始的实体,删除了一些属性,但我现在有一个不同的错误,令人担忧的是它是不确定的 好的,代码 [Table("Foo")] publi

我希望
Foo
有一个可选的
Bar
Bar
有一个可选的
Foo

我似乎设法让它工作,但我只在其中一个表上创建了一个额外的列,例如,它在SQL中只在其中一个表上创建了
InvitationId
,然后也在其中一个表上创建了
InvitationId
,尽管两个实体的设置方式相同,但设置方式相反

所以我想做一个更小的复制,这样我就可以问这个问题了,但是在这个过程中,虽然我刚刚复制了原始的实体,删除了一些属性,但我现在有一个不同的错误,令人担忧的是它是不确定的

好的,代码

[Table("Foo")]
public partial class Foo
{
    [Key]
    public Guid Id { get; set; }

    [Required]
    [StringLength(128)]
    public string Name { get; set; }

    // Referential

    [ForeignKey("Bar")]
    public Guid? BarId { get; set; }

    public virtual Bar Bar { get; set; }
}

[Table("Bar")]
public partial class Bar
{
    [Key]
    public Guid Id { get; set; }

    [Required]
    [StringLength(128)]
    public string Name { get; set; }

    // Referential

    [ForeignKey("Foo")]
    public Guid? FooId { get; set; }

    public virtual Foo Foo { get; set; }
}
在建模创建中的

    modelBuilder.Entity<Foo>()
        .HasOptional<Bar>(foo => foo.Bar)
        .WithOptionalPrincipal(bar => bar.Foo);
modelBuilder.Entity()
.has可选(foo=>foo.Bar)
.WithOptionalPrincipal(bar=>bar.Foo);
错误是:

在类型“Product.Data.Entities.Bar”上声明的导航属性“Foo”已配置有冲突的外键

原始图元仍存在于项目中,并且以完全相同的方式设置,只是它们具有更多属性,但创建时不会出错,只是其中一个具有无关的FK列

所以有很多问题:

  • 为什么我得到了额外的
    InvitationId
    列,而它已经有了
    InvitationId

  • 为什么我不能复制它

  • 为什么现在会出现错误?如果我解决了这个问题,如果我的原始实体没有相同的问题,它会帮助我处理它们吗

  • 在我上面的开场白中,实现目标的正确方式是什么

同时,我将开始一点一点地将
Foo
Bar
构建回
Invitation
Expectation
直到它变得有趣

更新

所以我最终得到了除了名字以外的所有原始实体的精确副本。这些副本导致了上述FK冲突错误,但原件没有

然后我删除了原件,并将副本重命名为其原始名称,没有更改任何属性或属性,错误消失了,我回到了无关FK专栏的原始版本

疯子


Luke

正如我在评论中提到的,因为有两种关系,并且可能在关系的每一方都有一个导航属性,我认为EF很难区分哪种导航属性是哪种关系的一部分。
我建议在您的
OnModelCreating

modelBuilder.Entity<Foo>().HasOptional(f => f.Bar)
                          .WithMany()
                          .HasForeignKey(f => f.BarId);

modelBuilder.Entity<Bar>().HasOptional(b => b.Foo)
                          .WithMany()
                          .HasForeignKey(b => b.FooId);
modelBuilder.Entity().has可选(f=>f.Bar)
.有很多
.HasForeignKey(f=>f.BarId);
modelBuilder.Entity().has可选(b=>b.Foo)
.有很多
.HasForeignKey(b=>b.FooId);

第一件事是在一对一关系中,一端必须是主体,另一端是从属,因此不能在两个实体中都指定FK属性。第二件事是,如果要使用FK属性,EF要求依赖实体的PK也应为FK:

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

public class Dependent
{
   [Key, ForeignKey("Principal")]
   public int PrincipalId{get;set;}

   public virtual Principal Principal{get;set;}
}
第三件事是EF允许您使用Fluent API在两侧配置一对一的可选关系,但您可以指定FK,因为正如我前面所说的,它也应该配置为PK,所以EF将在DB中为您处理该FK,这样您就有了一个额外的
邀请Id

要解决您的问题,您的模型应采用这种方式(删除FK属性):

并使用相同的Fluent Api配置:

 modelBuilder.Entity<Foo>()
        .HasOptional(foo => foo.Bar)
        .WithOptionalPrincipal(bar => bar.Foo);
modelBuilder.Entity()
.has可选(foo=>foo.Bar)
.WithOptionalPrincipal(bar=>bar.Foo);
关于为什么在您的真实代码中没有发生异常,我认为与@user2697817一样,您应该创建两种不同的关系,但我完全可以确保,因为我没有看到您的真实模型


第二个选项可能是@user2697817显示的解决方案,但在这种情况下,您将拥有两个不同的关系。

我认为您的问题是,两个表之间有两个关系,只有一个导航属性。在fluent API中,您说
Bar
上的
Foo
属性是一种关系的一部分,但随后您将其与数据注释相结合,并说它是另一种关系的一部分。如果这有意义的话?顺便说一句,我有一个关于非确定性奇怪性的理论。一旦我更改了实体的名称,错误就消失了,出现了额外的列问题,因此我猜测这些名称改变了EF schema ThingMy系统枚举和应用其逻辑的顺序。我认为目的是创建两个关系,因此每个实体上都有外键。我认为OP需要澄清,我们都给出了两种不同的解决方案。谢谢你的回答。我讨厌这种主要和依赖的想法。我有两个实体,
Foo
可能有
Bar
Bar
可能有
Foo
。就数据而言,
Foo
可以为null或
Bar
中的行ID,
Bar
可以为null或
Foo
中的行ID。简单?EF不能做到这一点吗?好吧,你所描述的与@user2697817所展示的解决方案非常吻合,这是模拟一对一关系的好方法,你将在两个实体中(以及在表上)都有FK属性@Octaviccl现在我在这条路上走得更远这个项目,你实际上是对的。虽然勾选的问题对于OP来说是正确的,正如你所怀疑的那样,我试图做的不是“正确的”。谢谢,我现在已经实现了上面的功能。谢谢。这一个的问题是它有许多
。我希望
Foo
有一个或零个
Bar
,反之亦然@
 modelBuilder.Entity<Foo>()
        .HasOptional(foo => foo.Bar)
        .WithOptionalPrincipal(bar => bar.Foo);