与EF5流畅映射的一对一或零关系

时间:2013-04-18 09:52:22

标签: entity-framework-5

我有三个实体:

public class MainEntity()
{
    public long Id { get; set; }

    public long EntityAId { get; set; }
    public EntityA OptionalEntityA { get; set; }

    public long EntityBId { get; set; }
    public EntityB OptionalEntityB { get; set; }

    public string SProp { get; set; }
}

public class EntityA()
{
    public long Id { get; set; }

    public long MainEntityId { get; set; }
    public MainEntity RequiredEntity { get; set; }
}

public class EntityB()
{
    public long Id { get; set; }

    public long MainEntityId { get; set; }
    public MainEntity RequiredEntity { get; set; }
}

所有三个实体都有自己的数据库生成的ID:

Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

如何定义MainEntity与EntityA和EntityB之间的关系以便:

  • MainEntity可能有零个或一个EntityA
  • MainEntity可能有零个或一个EntityB
  • EntityA必须有一个MainEntity
  • EntityB必须有一个MainEntity

在我的MainEntityConfigurationMap中,我定义了这样的关系:

HasOptional(m => m.OptionalEntityA).WithRequired(ea => ea.RequiredEntity);
HasOptional(m => m.OptionalEntityB).WithRequired(eb => eb.RequiredEntity);

查看生成的迁移,我将其用于EntityA:

        CreateTable(
            "dbo.EntityA",
            c => new
                {
                    Id = c.Long(nullable: false, identity: true),
                    MainEntityId = c.Long(nullable: false),
                })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.MainEntity", t => t.Id)
            .Index(t => t.Id);

实体框架在这里定义了一个共享主键,有没有办法避免这种情况并使MainEntityId对MainEntity.Id进行定位?

2 个答案:

答案 0 :(得分:2)

实体框架仅支持在共享主键之上的一对一关系(从属表中的PK也是FK到主表)。原因是依赖表中的FK必须是唯一的以强制执行一对一关系,但EF当前不支持唯一约束(PK除外)。

答案 1 :(得分:1)

并补充说@Ladislav Mrmka说的话......

以下是对各种一对一模式的全面研究 - 特别是如何使用FK-s而不是捆绑PK-s(但不要将你的希望提高到太高)。

Create a Unique Constraint To Enforce the Relationship as a One to One

归结为手动执行SQL(在种子或类似的Db初始化期间) - 这会添加UNIQUE CONSTRAINT ...

然而,即使在这种情况下,它也不会对您有用 - 或者不会对您进行更改。

如果我没有误会 - 您必须放弃一个导航属性 - 很可能是OptionEntityA/B - 因为唯一列不能支持NULL。