多对多实体框架+撰写主键

时间:2018-02-12 20:20:02

标签: entity-framework asp.net-mvc-5 entity-framework-6

嗨,朋友们,我与Compose Primary Key的关系有很多问题。

我有以下内容:

public class Empleado
{
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   [Key, Column(Order = 0)]
   public int Id { get; set; }

   [Required]
   [StringLength(100)]
   public string Nombre { get; set; }

   [Key, Column(Order = 1)]
   public int? IdentificacionId { get; set; }
   public Identificacion Identificacion { get; set; }

   [Required]
   [StringLength(11)]
   [Key, Column(Order = 2)]
   public string NoIdentificacion { get; set; }
}

// Entidad relación
public class EmpleadoNomina
{
   public int EmpleadoId { get; set; }
   public int NominaId { get; set; }
   public decimal Salario { get; set; }
   public int DescuentoLey { get; set; }
   public decimal? SalarioIngresoEgreso { get; set; }

   public Nomina Nomina { get; set; }
   public Empleado Empleado { get; set; }
}

// FluentApi
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
   // Constraint combinado TipoId + NoID
   modelBuilder.Entity<Empleado>().HasKey(x => new { x.IdentificacionId, x.NoIdentificacion });

   // Relación
   modelBuilder.Entity<EmpleadoNomina>().HasKey(k => new { k.NominaId, k.EmpleadoId });
}

创建关系表时会出现问题。为此添加了Employee_IdentificationId,Employee_NoIdentification列。而没有foreignkey的EmployeeId列。 enter image description here 另一个问题是:我不能使用.Find(id);示例:db.Empleados.Find(15);这会产生错误,因为它需要我传递三个键。

我只想删除额外的列Employee_IdentificationId,Employee_NoIdentification并仅使用EmpleadoId。

2 个答案:

答案 0 :(得分:0)

不要在Empleado上使用复合键 - 只需使用ID作为键。 Nomina也是如此。组合键用于桥表。此外,由于您已经在使用流畅的代码,因此您不需要注释。混合时行为可能很奇怪。

public class Empleado
{
   // This will be identity key by convention
   public int Id { get; set; }

   // These could be set in fluent code
   [Required]
   [StringLength(100)]
   public string Nombre { get; set; }
   public string NoIdentificacion { get; set; }

   // This will be an optional FK by convention
   public int? IdentificacionId { get; set; }
   public Identificacion Identificacion { get; set; }

   public virtual ICollection<Nomina> Nominas { get; set; }

}

public class Nomina 
{
   // This will be identity key by convention
   public int Id { get; set; }
   public string XXXXXX { get; set; }
   ... etc

   public virtual ICollection<Empleado> Empleados { get; set; }
}

public class EmpleadoNomina
{
   public int EmpleadoId { get; set; }
   public int NominaId { get; set; }
   public decimal Salario { get; set; }
   public int DescuentoLey { get; set; }
   public decimal? SalarioIngresoEgreso { get; set; }

   public Nomina Nomina { get; set; }
   public Empleado Empleado { get; set; }
}

// FluentApi
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Empleado>()
                .HasMany<Nomina>(e => e.Nominas)
                .WithMany(c => c.Empleado)
                .Map(cs =>
                        {
                            cs.MapLeftKey("Id");
                            cs.MapRightKey("Id");
                            cs.ToTable("EmpleadoNomina");
                        });
}

请参阅here

编辑:好的,如果你需要在Empleado上保留复合键,那么你需要用复合FK来引用它。所以你需要添加其他2个FK字段:

// Entidad relación
public class EmpleadoNomina
{
   public int EmpleadoId { get; set; }
   public int IdentificacionId { get; set; }
   public string NoIdentificacion { get; set; }

   public int NominaId { get; set; }
   public decimal Salario { get; set; }
   public int DescuentoLey { get; set; }
   public decimal? SalarioIngresoEgreso { get; set; }

   public Nomina Nomina { get; set; }
   public Empleado Empleado { get; set; }
}

然后是流利的代码:

modelBuilder.Entity<EmpleadoNomina>()
    .HasRequired(en => en.Empleado)
    .WithMany()
    .HasForeignKey(en => new {en.EmpleadoId, en.IdentificacionId , en.NoIdentificacion });

另外,我不确定IdentificacionId是否可以为空。请参阅here

答案 1 :(得分:0)

我使用Index Dataanotations解决了它,以创建Unique Composited Index而不是Composited主键(这是我的问题的原因)。

我从主类中删除了复合键,并将EmployeeNomine列表添加到两类实体中。

我改变了所有内容,如下所示,现在它运作良好。这就是我从一开始就想做的事情。

// Class 2
public class Empleado
{
   [Key]
   public int Id { get; set; }

   [Required]
   [StringLength(100)]
   public string Nombre { get; set; }

   [Index("IX_Identificacion", 1, IsUnique = true)]
   public int? IdentificacionId { get; set; }
   public Identificacion Identificacion { get; set; }

   [Required]
   [StringLength(11)]
   [Index("IX_Identificacion", 2, IsUnique = true)]
   public string NoIdentificacion { get; set; }

   public List<EmpleadoNomina> EmpleadoNominas { get; set; }
}

// Class 1
public class Nomina
{
   [Key]
   public int Id { get; set; }

   [Required]
   [StringLength(200)]
   public string Descripcion { get; set; }

   public int Frecuencia { get; set; }

   public int Dia { get; set; }

   public List<EmpleadoNomina> EmpleadoNominas { get; set; }
}

// Relation Entity (Table)
public class EmpleadoNomina
{
   public int EmpleadoId { get; set; }
   public int NominaId { get; set; }
   public decimal Salario { get; set; }
   public int DescuentoLey { get; set; }
   public decimal? SalarioIngresoEgreso { get; set; }

   public Nomina Nomina { get; set; }
   public Empleado Empleado { get; set; }
}

// FluentApi
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
   // Nominas -> Empleados
   modelBuilder.Entity<EmpleadoNomina>().HasKey(k => new { k.NominaId, k.EmpleadoId });
   modelBuilder.Entity<EmpleadoNomina>().HasRequired(e => e.Empleado).WithMany(n => n.EmpleadoNominas).HasForeignKey(r => r.EmpleadoId);
   modelBuilder.Entity<EmpleadoNomina>().HasRequired(n => n.Nomina).WithMany(n => n.EmpleadoNominas).HasForeignKey(n => n.NominaId);
}

这是我一直想做的。谢谢你的一切

enter image description here