Entity Framework 遗留数据库上的代码优先复合外键
Entity Framework Code First Composite Foreign Key on legacy DB
所以,这几天我一直在苦思冥想,搜索让我离解决方案还很远。
我有一个远未遵循 EF 代码约定的遗留数据库,我正在使用 EF Code First。
这是我的实际情况:(为简洁起见省略了不相关的字段)
[Table("PEDIDO")]
public class Pedido : IValidatableObject
{
[Key, Column(Order = 1), Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CODIGO { get; set; }
[Key, Column(Order = 2), ForeignKey("DadosCliente"), Required]
public int CLIENTE { get; set; }
public virtual Cliente DadosCliente { get; set; }
public virtual ICollection<MaterialPedido> DadosMateriaisPedido { get; set; }
}
[Table("MATERIAL_PEDIDO")]
public class MaterialPedido : IValidatableObject
{
[Key, Required, Column(Order = 1)]
public int NRPEDIDO { get; set; } // This column relates to Pedido.CODIGO
[Key, Required, Column(Order = 2), ForeignKey("DadosCliente")]
public int CLIENTE { get; set; }
public virtual Cliente DadosCliente { get; set; }
[Key, Required, Column(Order = 3)]
public string CODIGO { get; set; }
// Please note that this column is some sort of "virtual field". Its value should be hard-coded to "P" when relating to the table "PEDIDO"
}
public class EntitiesContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Pedido>()
.HasKey(p => new { p.CLIENTE, p.CODIGO })
.HasMany(x => x.DadosMateriaisPedido)
.WithOptional(p => p.Pedido)
.HasForeignKey(x => new { x.CLIENTE, x.NRPEDIDO })
.WillCascadeOnDelete(false);
}
}
截至目前,我收到以下错误:
ProjetoPI.EF.Pedido_DadosMateriaisPedido: : Multiplicity conflicts with the referential constraint in Role 'Pedido_DadosMateriaisPedido_Source' in relationship 'Pedido_DadosMateriaisPedido'. Because all of the properties in the Dependent Role are non-nullable, multiplicity of the Principal Role must be '1'.
Pedido_DadosMateriaisPedido_Target: : Multiplicity is not valid in Role 'Pedido_DadosMateriaisPedido_Target' in relationship 'Pedido_DadosMateriaisPedido'. Because the Dependent Role refers to the key properties, the upper bound of the multiplicity of the Dependent Role must be '1'.
我错过了什么?任何帮助将不胜感激!
所以,我终于知道发生了什么所以下面是我的解决方案以供将来参考,希望它能够帮助像我一样绝望的灵魂:
我的映射完全错误。 MATERIAL_PEDIDO 与 PEDIDO 没有关系(不确定我是否同意这种设计,但是...)并且 Entity Framework 不批准创建数据库中不存在的关系。还有第三个table,除了包含MaterialPedido的children,就是Pedido和MaterialPedido的关系
[我不能post图像,所以我将无法post数据库模型=()。所以我清除了所有关系并从头开始重塑。
以下是我的工作关系:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Pedido>()
.HasKey(p => new { p.CLIENTE, p.CODIGO })
.HasMany<DetalhePedido>(p => p.DetalhesPedido)
.WithRequired(dp => dp.Pedido)
.HasForeignKey(dp => new { dp.CLIENTE, dp.NRPEDIDO });
modelBuilder.Entity<MaterialPedido>()
.HasKey(mp => new { mp.NRPEDIDO, mp.CLIENTE, mp.CODIGO })
.HasMany<DetalhePedido>(mp => mp.DetalhesPedido)
.WithRequired(dp => dp.MaterialPedido)
.HasForeignKey(dp => new { dp.NRPEDIDO, dp.CLIENTE, dp.MATERIAL });
}
[Table("MATERIAL_PEDIDO")]
public class MaterialPedido : IValidatableObject
{
[Key, Required, Column(Order = 1)]
public int NRPEDIDO { get; set; }
[Key, Required, Column(Order = 2), ForeignKey("DadosCliente")]
public int CLIENTE { get; set; }
public virtual Cliente DadosCliente { get; set; }
[Key, Column(Order = 3)]
public string CODIGO { get; set; }
public virtual ICollection<DetalhePedido> DetalhesPedido { get; set; }
}
[Table("DETALHE_PEDIDO")]
public class DetalhePedido
{
[Key, Column(Order = 1)]
public int NRPEDIDO { get; set; }
[Key, Column(Order = 2)]
public int CLIENTE { get; set; }
[Key, Column(Order = 3)]
public string MATERIAL { get; set; }
[Key, Column(Order = 4)]
public string CODIGO { get; set; }
public virtual Pedido Pedido { get; set; }
public virtual MaterialPedido MaterialPedido { get; set; }
}
[Table("PEDIDO")]
public class Pedido : IValidatableObject
{
[Key, Column(Order = 1), DisplayName("Cód Pedido"), Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CODIGO { get; set; }
[Key, Column(Order = 2), Required, CustomValidation(typeof(GranitoEntities), "NotZero")]
public int CLIENTE { get; set; }
[ForeignKey("CLIENTE")]
public virtual Cliente DadosCliente { get; set; }
public virtual ICollection<DetalhePedido> DetalhesPedido { get; set; }
}
所以,这几天我一直在苦思冥想,搜索让我离解决方案还很远。
我有一个远未遵循 EF 代码约定的遗留数据库,我正在使用 EF Code First。
这是我的实际情况:(为简洁起见省略了不相关的字段)
[Table("PEDIDO")]
public class Pedido : IValidatableObject
{
[Key, Column(Order = 1), Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CODIGO { get; set; }
[Key, Column(Order = 2), ForeignKey("DadosCliente"), Required]
public int CLIENTE { get; set; }
public virtual Cliente DadosCliente { get; set; }
public virtual ICollection<MaterialPedido> DadosMateriaisPedido { get; set; }
}
[Table("MATERIAL_PEDIDO")]
public class MaterialPedido : IValidatableObject
{
[Key, Required, Column(Order = 1)]
public int NRPEDIDO { get; set; } // This column relates to Pedido.CODIGO
[Key, Required, Column(Order = 2), ForeignKey("DadosCliente")]
public int CLIENTE { get; set; }
public virtual Cliente DadosCliente { get; set; }
[Key, Required, Column(Order = 3)]
public string CODIGO { get; set; }
// Please note that this column is some sort of "virtual field". Its value should be hard-coded to "P" when relating to the table "PEDIDO"
}
public class EntitiesContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Pedido>()
.HasKey(p => new { p.CLIENTE, p.CODIGO })
.HasMany(x => x.DadosMateriaisPedido)
.WithOptional(p => p.Pedido)
.HasForeignKey(x => new { x.CLIENTE, x.NRPEDIDO })
.WillCascadeOnDelete(false);
}
}
截至目前,我收到以下错误:
ProjetoPI.EF.Pedido_DadosMateriaisPedido: : Multiplicity conflicts with the referential constraint in Role 'Pedido_DadosMateriaisPedido_Source' in relationship 'Pedido_DadosMateriaisPedido'. Because all of the properties in the Dependent Role are non-nullable, multiplicity of the Principal Role must be '1'. Pedido_DadosMateriaisPedido_Target: : Multiplicity is not valid in Role 'Pedido_DadosMateriaisPedido_Target' in relationship 'Pedido_DadosMateriaisPedido'. Because the Dependent Role refers to the key properties, the upper bound of the multiplicity of the Dependent Role must be '1'.
我错过了什么?任何帮助将不胜感激!
所以,我终于知道发生了什么所以下面是我的解决方案以供将来参考,希望它能够帮助像我一样绝望的灵魂:
我的映射完全错误。 MATERIAL_PEDIDO 与 PEDIDO 没有关系(不确定我是否同意这种设计,但是...)并且 Entity Framework 不批准创建数据库中不存在的关系。还有第三个table,除了包含MaterialPedido的children,就是Pedido和MaterialPedido的关系
[我不能post图像,所以我将无法post数据库模型=()。所以我清除了所有关系并从头开始重塑。
以下是我的工作关系:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Pedido>()
.HasKey(p => new { p.CLIENTE, p.CODIGO })
.HasMany<DetalhePedido>(p => p.DetalhesPedido)
.WithRequired(dp => dp.Pedido)
.HasForeignKey(dp => new { dp.CLIENTE, dp.NRPEDIDO });
modelBuilder.Entity<MaterialPedido>()
.HasKey(mp => new { mp.NRPEDIDO, mp.CLIENTE, mp.CODIGO })
.HasMany<DetalhePedido>(mp => mp.DetalhesPedido)
.WithRequired(dp => dp.MaterialPedido)
.HasForeignKey(dp => new { dp.NRPEDIDO, dp.CLIENTE, dp.MATERIAL });
}
[Table("MATERIAL_PEDIDO")]
public class MaterialPedido : IValidatableObject
{
[Key, Required, Column(Order = 1)]
public int NRPEDIDO { get; set; }
[Key, Required, Column(Order = 2), ForeignKey("DadosCliente")]
public int CLIENTE { get; set; }
public virtual Cliente DadosCliente { get; set; }
[Key, Column(Order = 3)]
public string CODIGO { get; set; }
public virtual ICollection<DetalhePedido> DetalhesPedido { get; set; }
}
[Table("DETALHE_PEDIDO")]
public class DetalhePedido
{
[Key, Column(Order = 1)]
public int NRPEDIDO { get; set; }
[Key, Column(Order = 2)]
public int CLIENTE { get; set; }
[Key, Column(Order = 3)]
public string MATERIAL { get; set; }
[Key, Column(Order = 4)]
public string CODIGO { get; set; }
public virtual Pedido Pedido { get; set; }
public virtual MaterialPedido MaterialPedido { get; set; }
}
[Table("PEDIDO")]
public class Pedido : IValidatableObject
{
[Key, Column(Order = 1), DisplayName("Cód Pedido"), Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CODIGO { get; set; }
[Key, Column(Order = 2), Required, CustomValidation(typeof(GranitoEntities), "NotZero")]
public int CLIENTE { get; set; }
[ForeignKey("CLIENTE")]
public virtual Cliente DadosCliente { get; set; }
public virtual ICollection<DetalhePedido> DetalhesPedido { get; set; }
}