0

我有两个这样的课程:

public class Event
{
    [Key]
    [Required]
    public long Id { get; set; }

    [InverseProperty("Event")          
    public virtual Record Record{ get; set; }
}


public class Record
{
    [Key]
    [Required]
    public int Id { get; set; }

    [ForeignKey("Event")]
    public long? EventId { get; set; }

    public virtual Event Event{ get; set; }
}

但是,我通过此设置得到了预期的多重性错误。我想要结束的是:

  • 没有记录而存在的事件

  • 记录没有事件的存在

  • 与记录一起存在的事件(并让记录存储事件 ID)

这可能吗,我必须使用FluentApi而不是Data Annotations吗?

我不想向 Event 表中添加任何字段或键。

4

2 回答 2

1

你是对的,只给关系的两侧之一一个外键。我首先认为双方都需要一个可为空的外键。但是,如果您这样做,那么事件 1 可能具有记录 2 的外键和事件 3 的外键以及记录 4 的外键,等等。

显然,在这些情况下,只有双方中的一方应该有外键。

查看配置一对零或一关系,我看到以下内容就足够了:

class Event
{
    public long Id { get; set; }
    public string Name { get; set; }

    // Every Event has zero or one Record
    public virtual Record Record { get; set; }
}
class Record
{
    public long Id { get; set; }
    public string Name { get; set; }

    // Every Record has zero or one Event
    public virtual Event Event { get; set; }
}

和 DbContext:

class OneToOneContext : DbContext
{
    public OneToOneContext(): base("OneToOneDemo"){}

    public DbSet<Event> Events { get; set; }
    public DbSet<Record> Records { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Record>()
            .HasOptional(record => record.Event)
            .WithOptionalDependent(ev => ev.Record)
            .WillCascadeOnDelete(false);
    }
}

fluent API 通知模型构建器每个 Record 有零个或一个 Event,有零个或一个 Record。记录被声明为依赖。这确保了 Record 在这个关系中会有外来的。

请注意,我不必添加任何其他属性。因为我遵循了代码优先约定实体框架能够检测到主键和表之间的关系。

我能够添加:没有记录的事件、没有事件的记录、有记录的事件和有事件的记录:

using (var dbContext = new OneToOneContext())
{
    dbContext.Events.Add(new Event { Name = "Event without Record"});
    dbContext.Records.Add(new Record { Name = "Record without Event" });

    dbContext.Events.Add(new Event
    {
        Name = "Event A with Record",
        Record = new Record { Name = "Record of Event A" },
    });

    dbContext.Records.Add(new Record
    {
        Name = "Record B with Event",
        Event = new Event { Name = "Event of Record B" },
    });

    dbContext.SaveChanges();
}
于 2019-01-21T13:23:55.180 回答
1

在 EF 6.x 中,您必须使用 Fluent API 进行如下配置:

 modelBuilder.Entity<Record>()
       .HasOptional(x => x.Event)
       .WithOptionalPrincipal(x => x.Record)
       .Map(a => a.MapKey("RecordId"));

在 EF Core 中,您当前的模型设置已经足够好了!不需要再做任何事了。

于 2019-01-21T12:56:56.613 回答