EF code-第一单对一的关系:多重不是在关系中的作用*有效 [英] EF Code-First One-to-one relationship: Multiplicity is not valid in Role * in relationship

查看:416
本文介绍了EF code-第一单对一的关系:多重不是在关系中的作用*有效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做到以下几点:

public class class1()
{
    public int Id {get;set;}
    [ForeignKey("Class2")]
    public int Class2Id {get;set;}
    public virtual Class2 Class2 {get;set;}
}

public class class2()
{
    public int Id {get;set;}
    [Required]
    public virtual int Class1Id {get;set;}
    [Required]
    [ForeignKey("Class1Id")]
    public Class1 Class1 {get;set;}
}

不过,我尝试迁移我的数据库我得到以下错误每次:

However every time I try to migrate my database I get the following error:

Class1_Class2_Target:多重不作用有效
  在关系'Class2_Class1'Class2_Class1_Target。由于
  取决于角色属性不是关键性质,上限
  从属角色的多重性必须是'*'。

Class1_Class2_Target: : Multiplicity is not valid in Role 'Class2_Class1_Target' in relationship 'Class2_Class1'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

还有什么比这里是问题?

What could be the issue here?

推荐答案

您模型并不是一个1:1的关系。你仍然可以拥有的许多类2 引用相同的有一个 1级对象。另外,你的模型并不能保证一个类2 指的是 1级也是由这个退回 1级对象 - 1级可以引用任何类2 对象

Your model is not a 1:1 association. You can still have many Class2 objects referring to the same one Class1 object. Also, your model doesn't guarantee that a Class2 referring to a Class1 is also referred back by this Class1 object — Class1 can refer to any Class2 object.

要保证(排序)1的常用方法:1联想在SQL是有对的主要的实体和表一为的依赖的实体,其中,相关表的主键也是一个外键校长:

The common way to guarantee (sort of) a 1:1 association in SQL is to have a table for the principal entity and one for the dependent entity where the primary key in the dependent table also is a foreign key to the principal:

(这里的 1级是主要的)

现在在关系数据库中,这仍然不能保证一个1:1的关联(这就是为什么我说:'那种')。这是一个 1:0..1 的关联。可以有一个 1级没有类2 。事实是,真正的1:1协会SQL是不可能的,因为没有在不同的表中插入两行同步的语言结构。 1:0..1是我们得到的最接近

Now in a relational database, this still doesn't guarantee a 1:1 association (that's why I said 'sort of'). It's a 1:0..1 association. There can be a Class1 without a Class2. The truth is, genuine 1:1 associations are impossible in SQL, because there is no language construct that inserts two rows in different tables synchronously. 1:0..1 is the closest we get.

流利的映射

为了模拟这种关联在EF可以用流利的API。下面是做到这一点的标准方式:

To model this association in EF you can use the fluent API. Here's the standard way to do it:

class Class1Map : EntityTypeConfiguration<Class1>
{
    public Class1Map()
    {
        this.HasKey(c => c.Id);
        this.Property(c => c.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        this.HasRequired(c1 => c1.Class2).WithRequiredPrincipal(c2 => c2.Class1);
    }
}

和上下文:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Configurations.Add(new Class1Map());
}

这就是离开你的类:

And this is left of your classes:

public class Class1()
{
    public int Id {get;set;}
    public virtual Class2 Class2 {get;set;}
}

public class Class2()
{
    public int Id {get;set;}
    public virtual Class1 Class1 {get;set;}
}

有没有办法在模型中配置备用外键的属性,因为只有参与FK的必须的依赖的主键。

There is no way to configure alternate foreign key properties in the model, because the only FK involved has to be the dependent's primary key.

这个模型奇怪的是,EF不从创建(并保存)一个 1级对象的没有的一个<$阻止你C $ C>类2 。我觉得EF应该是能够验证保存更改之前这个要求,但是,很显然,事实并非如此。同样,有一些方法可以删除类2 对象而不删除其 1级父。所以这个 HasRequired - WithRequired 对并不像看起来那样严格(也应该)

The strange thing about this model is that EF doesn't stop you from creating (and saving) a class1 object without a class2. I think EF should be capable of validating this requirement before saving changes, but, apparently, it doesn't. Likewise, there are ways to delete a class2 object without deleting its class1 parent. So this HasRequired - WithRequired pair is not as stringent as it looks (and should be).

数据注解

要获得这项权利的在code的唯一方法的是数据的注释。 (当然数据库模型将仍然无法执行1:1)

The only way to get this right in code is by data annotations. (Of course the database model will still not be able to enforce 1:1)

public class Class1()
{
    public int Id {get;set;}
    [Required]
    public virtual Class2 Class2 {get;set;}
}

public class Class2()
{
    [Key, ForeignKey("Class1")]
    public int Id {get;set;}
    [Required]
    public virtual Class1 Class1 {get;set;}
}

[重点,ForeignKey的(1级)] 注解告诉EF的 1级是主要实体。

The [Key, ForeignKey("Class1")] annotation tells EF that Class1 is the principal entity.

数据说明在许多API发挥作用,它可以是一种诅咒,因为每个API选择自己的子集来实现,但在这里就派上用场了,因为现在EF不只是他们用来的设计数据模型,而且要的验证的实体。现在,如果你尝试保存 1级对象没有类2 你会得到一个验证错误。

Data annotations play a role in many APIs, which can be a curse, because each API chooses its own subset to implement, but here it comes in handy, because now EF not only uses them to design the data model, but also to validate entities. Now if you try to save a class1 object without a class2 you'll get a validation error.

这篇关于EF code-第一单对一的关系:多重不是在关系中的作用*有效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆