实体框架中 1:1 关系中关联的主体端意味着什么

发布于 2024-11-17 17:54:29 字数 457 浏览 3 评论 0原文

public class Foo
{
    public string FooId{get;set;}
    public Boo Boo{get;set;}
}


public class Boo
{
    public string BooId{get;set;}
    public Foo Foo{get;set;}
}

当我收到错误时,我试图在实体框架中执行此操作:

无法确定类型之间关联的主体端 “ConsoleApplication5.Boo”和“ConsoleApplication5.Foo”。 该关联的主体端必须使用以下任一方式显式配置: 关系流畅的 API 或数据注释。

我在 StackOverflow 上看到了有关此错误的解决方案的问题,但我想了解术语“主体端”的含义。

public class Foo
{
    public string FooId{get;set;}
    public Boo Boo{get;set;}
}


public class Boo
{
    public string BooId{get;set;}
    public Foo Foo{get;set;}
}

I was trying to do this in Entity Framework when I got the error:

Unable to determine the principal end of an association between the types
'ConsoleApplication5.Boo' and 'ConsoleApplication5.Foo'.
The principal end of this association must be explicitly configured using either the
relationship fluent API or data annotations.

I have seen questions on StackOverflow with a solution for this error, but I want to understand what the term "principal end" means.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清泪尽 2024-11-24 17:54:29

在一对一关系中,一端必须是主体,而另一端必须是从属。主端是首先插入的端,并且可以在没有从属端的情况下存在。从属端是必须插入到主体之后的端,因为它具有主体的外键。

如果是实体框架,则依赖的 FK 也必须是它的 PK,因此在您的情况下,您应该使用:

public class Boo
{
    [Key, ForeignKey("Foo")]
    public string BooId{get;set;}
    public Foo Foo{get;set;}
}

或流畅映射

modelBuilder.Entity<Foo>()
            .HasOptional(f => f.Boo)
            .WithRequired(s => s.Foo);

In one-to-one relation one end must be principal and second end must be dependent. Principal end is the one which will be inserted first and which can exist without the dependent one. Dependent end is the one which must be inserted after the principal because it has foreign key to the principal.

In case of entity framework FK in dependent must also be its PK so in your case you should use:

public class Boo
{
    [Key, ForeignKey("Foo")]
    public string BooId{get;set;}
    public Foo Foo{get;set;}
}

Or fluent mapping

modelBuilder.Entity<Foo>()
            .HasOptional(f => f.Boo)
            .WithRequired(s => s.Foo);
黯淡〆 2024-11-24 17:54:29

您还可以使用 [必需]数据注释属性来解决这个问题:

public class Foo
{
    public string FooId { get; set; }

    public Boo Boo { get; set; }
}

public class Boo
{
    public string BooId { get; set; }

    [Required]
    public Foo Foo {get; set; }
}

Boo需要Foo

You can also use the [Required] data annotation attribute to solve this:

public class Foo
{
    public string FooId { get; set; }

    public Boo Boo { get; set; }
}

public class Boo
{
    public string BooId { get; set; }

    [Required]
    public Foo Foo {get; set; }
}

Foo is required for Boo.

爱给你人给你 2024-11-24 17:54:29

这是参考@Ladislav Mrnka关于使用流畅的api配置一对一关系的答案。

有一种情况,依赖的 FK 必须是它的 PK 是不可行的。

例如,Foo 已经与 Bar 具有一对多关系。

public class Foo {
   public Guid FooId;
   public virtual ICollection<> Bars; 
}
public class Bar {
   //PK
   public Guid BarId;
   //FK to Foo
   public Guid FooId;
   public virtual Foo Foo;
}

现在,我们必须在 Foo 和 Bar 之间添加另一个一对一的关系。

public class Foo {
   public Guid FooId;
   public Guid PrimaryBarId;// needs to be removed(from entity),as we specify it in fluent api
   public virtual Bar PrimaryBar;
   public virtual ICollection<> Bars;
}
public class Bar {
   public Guid BarId;
   public Guid FooId;
   public virtual Foo PrimaryBarOfFoo;
   public virtual Foo Foo;
}

以下是如何使用 Fluent api 指定一对一关系:

modelBuilder.Entity<Bar>()
            .HasOptional(p => p.PrimaryBarOfFoo)
            .WithOptionalPrincipal(o => o.PrimaryBar)
            .Map(x => x.MapKey("PrimaryBarId"));

请注意,添加时需要删除 PrimaryBarId,因为我们是通过 Fluent api 指定的。

另请注意,方法名称 [WithOptionalPrincipal()][1] 有点讽刺。在本例中,校长是 Bar。 msdn 上的 WithOptionalDependent() 描述使其成为可能更清楚。

This is with reference to @Ladislav Mrnka's answer on using fluent api for configuring one-to-one relationship.

Had a situation where having FK of dependent must be it's PK was not feasible.

E.g., Foo already has one-to-many relationship with Bar.

public class Foo {
   public Guid FooId;
   public virtual ICollection<> Bars; 
}
public class Bar {
   //PK
   public Guid BarId;
   //FK to Foo
   public Guid FooId;
   public virtual Foo Foo;
}

Now, we had to add another one-to-one relationship between Foo and Bar.

public class Foo {
   public Guid FooId;
   public Guid PrimaryBarId;// needs to be removed(from entity),as we specify it in fluent api
   public virtual Bar PrimaryBar;
   public virtual ICollection<> Bars;
}
public class Bar {
   public Guid BarId;
   public Guid FooId;
   public virtual Foo PrimaryBarOfFoo;
   public virtual Foo Foo;
}

Here is how to specify one-to-one relationship using fluent api:

modelBuilder.Entity<Bar>()
            .HasOptional(p => p.PrimaryBarOfFoo)
            .WithOptionalPrincipal(o => o.PrimaryBar)
            .Map(x => x.MapKey("PrimaryBarId"));

Note that while adding PrimaryBarId needs to be removed, as we specifying it through fluent api.

Also note that method name [WithOptionalPrincipal()][1] is kind of ironic. In this case, Principal is Bar. WithOptionalDependent() description on msdn makes it more clear.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文