2017-06-13 119 views
0

有没有办法在实体框架中创建一对一或多个关系?我已经看到很多示例显示1到0 .. *的关系,但我想确保在给定示例中Foo只能存在,如果它至少有一个Bar。EF 1至1 .. *关系

class Foo 
{ 
    List<Bar> Bars { get; set; } 
} 

class Bar 
{ 
    public Foo Foo { get; set; } 
} 

我看,这是不容易被SQL实现,因为我想在富表而不是在酒吧桌子一种NOT NULL,但实体框架处理呢?

我意识到我问错了问题,因为我实际上寻找0..1 1 .. *关系,这是显著不同。 This是我想问的问题。

回答

0

在我意识到的任何SQL数据库中,不可能有真正的1对1关系。虽然集合论允许1比1,但实际上这很难实现。

这基本上是鸡和鸡蛋的情况。您无法创建Foo,因为您没有酒吧,并且您无法创建酒吧,因为还没有Foo。创建1到1所需的约束基本上阻止您插入任何实际行。

现在,您可以禁用约束,插入数据,然后重新启用它们,但这是一个真正破坏了约束条件的hacky kludge。

所以只需接受1到0 .. *然后继续。

0

实施此类解决方案的困难和可能性在下面的示例中讨论。


映射一到一个

映射一到一个(当需要双方)也是一个棘手的事情。

让我们想象一下如何用外键表示它。同样,People中的CarId,其参考Car中的CarId,以及Car中的PersonId,其参考People中的PersonId

现在如果你想插入汽车记录会发生什么?为了获得成功,必须在本赛车记录中指定PersonId,因为这是必需的。对于此PersonId有效,必须存在People中的相应记录。好的,让我们继续并插入人员记录。但为了取得这个成功,一个有效的CarId必须在人员记录—中,但该车还没有插入!这不可能,因为我们必须先插入引用的人员记录。但是我们不能插入引用的人员记录,因为它引用了汽车记录,所以必须先插入(外键 - ception :))。

所以这也不能用'逻辑'的方式表示。再次,您必须删除其中一个外键。你放弃哪一个取决于你。留有外键的一面称为“依赖”,没有外键的一面称为“主体”。再次,为了确保依赖项中的唯一性,PK必须是FK,因此不支持添加FK列并将其导入到模型中。

所以这里的配置:

public class CarEntityTypeConfiguration : EntityTypeConfiguration<Car> 
{ 
    public CarEntityTypeConfiguration() 
    { 
    this.HasRequired(c => c.Person).WithRequiredDependent(p => p.Car); 
    this.HasKey(c => c.PersonId); 
    } 
} 

现在,你真的应该得到它的逻辑:)只要记住,你可以选择对方为好,只是要小心使用从属/校长WithRequired版本(你仍然需要在车上配置PK)。

public class PersonEntityTypeConfiguration : EntityTypeConfiguration<Person> 
{ 
    public PersonEntityTypeConfiguration() 
    { 
    this.HasRequired(p => p.Car).WithRequiredPrincipal(c => c.Person); 
    } 
} 

如果检查DB模式,你会发现,这是完全一样的,因为它是在一个对一或零解的情况。这是因为再次,这不是由模式强制执行,而是由EF本身执行。如此反复,要小心:)

0

接近你可以得到的是这样的:

class Foo 
{ 
    List<Bar> Bars { get; set; } 

    [Required] 
    public int PrimaryBarId { get; set; } 
    public Bar PrimaryBar { get; set; } 
} 

class Bar 
{ 
    public Foo Foo { get; set; } 
} 

但是请注意,该数据库将不会强制

aFoo.PrimaryBar.FooId == aFoo。 Id

由于圆形FKs,这种模型很难更新。