EF6配置必需与可选的关系(一对零或一对一)

时间:2019-05-20 20:46:40

标签: c# entity-framework entity-framework-6 relationship

我有两个名为的数据库表

SegmentSet SegmentSetGeometry

它们都具有称为SegmentSetId的主键。 (SegmentSetGeometry(相关)segmentSetId是SegmentSet(主)的外键。

SegmentSet可以具有0或1个SegmentSetGeometries

我有两个表示这些表的类,分别为SegmentSetSegmentSetGeometry

public class SegmentSet
{
    public long SegmentSetId { get; set; }
    // ...
    public virtual SegmentSetGeometry SegmentSetGeometry { get; set; }
}

public class SegmentSetGeometry
{
    public long SegmentSetId { get; set; }
    public DbGeometry Geometry { get; set; }

    public virtual SegmentSet SegmentSet { get; set; }
}

这是它们的配置:

public class SegmentSetConfiguration: EntityTypeConfiguration<SegmentSet>
{
    public SegmentSetConfiguration()
    {
        ToTable("SegmentSet");
        HasKey(x => x.SegmentSetId);

        // ...

        HasOptional(x => x.SegmentSetGeometry)
            .WithRequired(x => x.SegmentSet);
    }
}

public class SegmentSetGeometryConfiguration : EntityTypeConfiguration<SegmentSetGeometry>
{
    public SegmentSetGeometryConfiguration()
    {
        ToTable("SegmentSetGeometry");
        HasKey(x => x.SegmentSetId);
    }
}

尝试从数据库中获取SegmentSet时出现以下错误:

Invalid column name 'SegmentSet_SegmentSetId'.

我找到了此引用https://docs.microsoft.com/en-us/ef/ef6/modeling/code-first/fluent/relationships,并决定切换关系并尝试:

public class SegmentSetConfiguration: EntityTypeConfiguration<SegmentSet>
{
    public SegmentSetConfiguration()
    {
        ToTable("SegmentSet");
        HasKey(x => x.SegmentSetId);

        // ...
    }
}

public class SegmentSetGeometryConfiguration : EntityTypeConfiguration<SegmentSetGeometry>
{
    public SegmentSetGeometryConfiguration()
    {
        ToTable("SegmentSetGeometry");
        HasKey(x => x.SegmentSetId);
        HasRequired(x => x.SegmentSet)
            .WithOptional(x=>x.SegmentSetGeometry);

    }
}

但是仍然不起作用。我正在使用他们给出的示例,但该示例无法正常工作,而且我查看了所有类似的堆栈溢出问题,但仍然无法正常工作

1 个答案:

答案 0 :(得分:0)

要将这两者映射在一起,您应该从关系的必需方面进行映射,并且只能从这一方面进行映射。映射双方都可能导致EF出现乱码,这可能会导致您遇到问题。

public class SegmentSet
{
    public long SegmentSetId { get; set; }
    // ...
    public virtual SegmentSetGeometry Geometry { get; set; }
}

public class SegmentSetGeometry
{
    public long SegmentSetId { get; set; }
    // ...
    public virtual SegmentSet SegmentSet { get; set; }
}

public class SegmentSetConfiguration: EntityTypeConfiguration<SegmentSet>
{
    public SegmentSetConfiguration()
    {
        ToTable("SegmentSets");
        HasKey(x => x.SegmentSetId);
        // Note: Do not map the HasOptional here... Only map the required on the other side.
    }
}

public class SegmentSetGeometryConfiguration : EntityTypeConfiguration<SegmentSetGeometry>
{
    public SegmentSetGeometryConfiguration()
    {
        ToTable("SegmentSetGeometries");
        HasKey(x => x.SegmentSetId);
        HasRequired(x => x.SegmentSet)
            .WithOptional(x=>x.Geometry);

    }
}

使用1..0 / 1关系的每个表上的PK应该可以正常工作。

编辑:还值得检查是否正在加载实体配置。这可能解释了英孚退回常规。在DbContext中:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.Configurations.AddFromAssembly(GetType().Assembly);
}

以上假设实体类型配置与DbContext定义在同一程序集中。否则:typeof(SegmentSetGeometryConfiguration).Assembly可以解决问题。