EF - Code First - 具有多个一对零或一对一的关系

EF - Code First - Having Multiple One to Zero or One Relationships

我正在开发一些调度程序 类,但在首先使用代码创建多个一对零或一对一关系后,我遇到了麻烦。

议程Class

public class Agenda
{
    public int AgendaId { get; set; }

    //Possible Owners of this Agenda
    public int? RoomId { get; set; }
    public Room Room { get; set; }

    public int? TrainerId { get; set; }
    public Trainer Trainer { get; set; }
}

房间Class

public class Room
{
    public int RoomId { get; set; }

    public string description { get; set; }

    //Without the [Required] gives me an error
    //Unable to determine the principal end of an association between the types...
    public int AgendaId { get; set; }
    [Required]
    public Agenda Agenda { get; set; }
}

训练师Class

public class Trainer
{
    public int TrainerId { get; set; }

    public string name { get; set; }

    //Without the [Required] gives me an error
    //Unable to determine the principal end of an association between the types...
    public int AgendaId { get; set; }
    [Required]
    public Agenda Agenda { get; set; }
}

我在创建房间或培训师时需要始终有一个议程,而议程只能属于一个房间或培训师,而不能同时属于两者。

到目前为止,我设法创建了关系,但现在我遇到了另一个问题,当我尝试将新记录插入表 Room 或 Trainer 时说:

Cannot insert explicit value for identity column in table when IDENTITY_INSERT is set to OFF

Code First 刚刚将两端创建为 principals/dependent,例如:我不能插入没有议程的新 Room/Trainer,也不能插入没有 Room/Trainer 的议程。

谢谢大家的帮助。

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public int AgendaId { get; set; }

您应该为身份问题添加此属性,这应该可以解决问题。顺便说一句,您需要为此定义什么是主键,这可能会出现问题。

一到 Zero/One 关系通过在相关实体上共享相同的 ID 投射到数据库中

public class Agenda
{
    [Key]
    public int Id { get; set; }
    public virtual AgendaRoom Room { get; set; }
    public virtual AgendaTrainer Trainer { get; set; }
}

public abstract class AgendaOneToOne
{
    [Key, ForeignKey( nameof( Agenda ) )]
    public int? Id { get; set; }
    public virtual Agenda Agenda { get; set; }
}

public class AgendaTrainer : AgendaOneToOne
{
    public string Name { get; set; }
}

class AgendaRoom : AgendaOneToOne
{
    public string Description { get; set; }
}

此处 Agenda.RoomAgenda.Trainer

具有一对 Zero/One 关系

那种关系有tutorial

更新

看来您正在寻找不同的东西...所以看看这个模型

public class DataContext : DbContext
{
    public DataContext()
        : base( "name=DataContext" )
    {
    }

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

        var trainer = modelBuilder.Entity<Trainer>();
        trainer.HasKey( e => e.Id );
        trainer.Property( e => e.Name ).IsRequired().HasMaxLength( 100 );

        var room = modelBuilder.Entity<Room>();
        room.HasKey( e => e.Id );
        room.Property( e => e.Name ).IsRequired().HasMaxLength( 100 );

        var agenda_owner = modelBuilder.Entity<AgendaOwner>();
        agenda_owner.HasKey( e => e.Id );
        agenda_owner.Property( e => e.Information ).IsOptional().HasMaxLength( 500 );

        var agenda = modelBuilder.Entity<Agenda>();
        agenda.HasKey( e => e.Id );
        agenda.HasRequired( e => e.Owner ).WithRequiredPrincipal( e => e.Agenda );

        var agenda_room = modelBuilder.Entity<AgendaRoom>();
        agenda_room.HasRequired( e => e.Room ).WithMany( e => e.Agendas ).HasForeignKey( e => e.Room_Id ).WillCascadeOnDelete( false );
        agenda_room.Property( e => e.RoomInformation ).IsOptional().HasMaxLength( 500 );

        var agenda_trainer = modelBuilder.Entity<AgendaTrainer>();
        agenda_trainer.HasRequired( e => e.Trainer ).WithMany( e => e.Agendas ).HasForeignKey( e => e.Trainer_Id ).WillCascadeOnDelete( false );
        agenda_trainer.Property( e => e.TrainerInformation ).IsOptional().HasMaxLength( 500 );
    }

    public virtual DbSet<Agenda> Agendas { get; set; }
    public virtual DbSet<AgendaOwner> AgendaOwners { get; set; }
    public virtual DbSet<Room> Rooms { get; set; }
    public virtual DbSet<Trainer> Trainers { get; set; }

}

public class Trainer
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<AgendaTrainer> Agendas { get; set; }
}

public class Room
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<AgendaRoom> Agendas { get; set; }
}

public class Agenda
{
    public int Id { get; set; }
    public virtual AgendaOwner Owner { get; set; }
}

public class AgendaOwner
{
    public int Id { get; set; }
    public virtual Agenda Agenda { get; set; }
    public string Information { get; set; }
}

public class AgendaTrainer : AgendaOwner
{
    public int? Trainer_Id { get; set; }
    public virtual Trainer Trainer { get; set; }

    public string TrainerInformation { get; set; }
}

public class AgendaRoom : AgendaOwner
{
    public int? Room_Id { get; set; }
    public virtual Room Room { get; set; }

    public string RoomInformation { get; set; }
}

和一个简单的用例

static void Main( string[] args )
{

    using ( var db = new DataContext() )
    {
        Room room_big = db.Rooms.FirstOrDefault( e => e.Name == "Big" );
        if ( room_big == null )
        {
            room_big = new Room
            {
                Name = "Big",
            };
            db.Rooms.Add( room_big );
        }

        var agenda_1 = new Agenda
        {
            Owner = new AgendaRoom
            {
                Room = room_big,
                Information = "Some information",
                RoomInformation = "Some information for the room",
            },
        };
        db.Agendas.Add( agenda_1 );
        db.SaveChanges();

        Trainer trainer_peter = db.Trainers.FirstOrDefault( e => e.Name == "Peter" );
        if ( trainer_peter == null )
        {
            trainer_peter = new Trainer
            {
                Name = "Peter",                        
            };
            db.Trainers.Add( trainer_peter );
        }

        var agenda_2 = new Agenda
        {
            Owner = new AgendaTrainer
            {
                Trainer = trainer_peter,
                Information = "Some information",
                TrainerInformation = "Some information for the trainer",
            },
        };

        db.Agendas.Add( agenda_2 );
        db.SaveChanges();

    }

}