C# EF-代码优先-具有多个一对零或一关系
我正在开发一些调度类,在首先用代码创建多个一对零或一关系之后,我遇到了麻烦 议程类C# EF-代码优先-具有多个一对零或一关系,c#,asp.net-mvc,entity-framework,ef-code-first,entity-framework-migrations,C#,Asp.net Mvc,Entity Framework,Ef Code First,Entity Framework Migrations,我正在开发一些调度类,在首先用代码创建多个一对零或一关系之后,我遇到了麻烦 议程类 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 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; }
}
客房类
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; }
}
培训班
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; }
}
当我创建房间或培训师时,我需要始终有一个日程安排,日程安排只能属于房间或培训师,而不能同时属于两者
到目前为止,我成功地建立了关系,但现在我面临另一个问题,当我试图在会议室或培训师处插入新记录时,我说:
当identity\u insert设置为OFF时,无法在表中插入identity列的显式值
Code First刚刚创建了作为负责人/相互依赖的两端,例如:我不能插入没有议程的新房间/培训师,也不能插入没有房间/培训师的议程
谢谢大家的帮助
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public int AgendaId { get; set; }
您应该为标识问题添加此属性,这将解决问题。顺便说一下,您需要定义什么是主键,这可能会出现问题。通过在相关实体上共享相同的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.Room
和Agenda.Trainer
这种关系有其特殊性
更新
看起来你在寻找不同的东西。。。看看这个模型
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; }
}
你映射过你的POCO吗?您是否使用数据批注或Fluent api来映射它们?您好,我使用的是数据批注,映射的内容没有超出我显示的内容,只是创建了代码,创建了一个新的迁移,更新了数据库,当我尝试向表中插入一条新记录时,我收到了该错误。但是模型看起来是错误的(出于好奇,看看迁移和生成的表会很有趣)-关系的两端不能都有FK。在
Trainer
和Room
中不应存在属性AgendaId
。谢谢,这确实解决了问题。只是出于好奇,在这种情况下,是否可以使所有类都有自己的独立主键?不,不是一对一关系。独立实体通过Onr-To-Many或多对多绑定在一起relations@JoséLourenço请检查我的更新-如果我必须实现它,我会选择该模型(根据给定的信息)
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();
}
}