EF 5,一对多,多个表

时间:2013-05-22 16:46:55

标签: collections entity-framework-5 one-to-many

我在以下课程中遇到一些麻烦:

public class TwoVariableDetails
{
    public TwoVariableDetails()
    {    
        MovementsPerBlocks = new HashSet<MovementsRow>();
        MovementsPerShiftTypes = new HashSet<MovementsRow>();
        MovementsPerMachines = new HashSet<MovementsRow>();
        MovementsPerShifts = new HashSet<MovementsRow>();
    }

    [Key]
    public Guid TwoVariableDetailsId { get; set; }

    [Required]
    [MaxLength(50)]
    public string Name { get; set; }

    [Required]
    [MaxLength(1000)]
    [DataType(DataType.MultilineText)]
    public string Description { get; set; }        

    public virtual ICollection<MovementsRow> MovementsPerBlocks { get; set; }
    public virtual ICollection<MovementsRow> MovementsPerShiftTypes { get; set; }
    public virtual ICollection<MovementsRow> MovementsPerMachines { get; set; }
    public virtual ICollection<MovementsRow> MovementsPerShifts { get; set; }      

}

[Table("Movement")]
public class MovementsRow
{
    public MovementsRow()
    {
        MovementsCells = new HashSet<MovementsCell>();
    }
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [CsvField(Ignore = true)]
    public Guid MovementId { get; set; }

    [Required]
    public int RowNo { get; set; }

    [Required]
    [CsvField(Ignore = true)]
    public Guid ModelId { get; set; }

    [ForeignKey("ModelId")]
    [CsvField(Ignore = true)]
    public virtual TwoVariableDetails Model { get; set; }

    [TypeConverter(typeof(MovementsCellTypeConverter))]
    public virtual ICollection<MovementsCell> MovementsCells { get; set; }

}

[Table("MovementCell")]
public class MovementsCell
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [CsvField(Ignore = true)]
    public Guid CellId { get; set; }

    [Required]
    public int ColumnNo { get; set; }

    [Required]
    public int Count { get; set; }

    [Required]
    [CsvField(Ignore = true)]
    public Guid MovementId { get; set; }

    [ForeignKey("MovementId")]
    [CsvField(Ignore = true)]
    public virtual MovementsRow Model { get; set; }
}

当我尝试将其保存到数据库时,我收到以下错误:

    The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.Movement_dbo.TwoVariableDetails_ModelId". The conflict occurred in database "aspnet-GreenCranes.UI-20130516", table "dbo.TwoVariableDetails", column 'TwoVariableDetailsId'.

声明已经终止。

这是我用来保存的代码:

twoVariableDetails.TwoVariableDetailsId = Guid.NewGuid();
_context.TwoVariableDetailsModels.Add(twoVariableDetails);
_context.SaveChanges();

我的表格如下:

Movement
    - Column    
        - MovementId
        - RowNo
        - ModelId(FK, uniqueidentifier, not null)
        - TwoVariableDetails_TwoVariableDetailsId(FK, uniqueidentifier, null)
        - TwoVariableDetails_TwoVariableDetailsId2(FK, uniqueidentifier, null)
        - TwoVariableDetails_TwoVariableDetailsId3(FK, uniqueidentifier, null)
        - TwoVariableDetails_TwoVariableDetailsId4(FK, uniqueidentifier, null)
    - Keys
        - FK_dbo.Movement_dbo.TwoVariableDetails_ModelId
        - FK_dbo.Movement_dbo.TwoVariableDetails_TwoVariableDetails_TwoVariableDetailsId
        - FK_dbo.Movement_dbo.TwoVariableDetails_TwoVariableDetails_TwoVariableDetailsId1
        - FK_dbo.Movement_dbo.TwoVariableDetails_TwoVariableDetails_TwoVariableDetailsId2
        - FK_dbo.Movement_dbo.TwoVariableDetails_TwoVariableDetails_TwoVariableDetailsId3

我不确定我的方法有什么问题。我应该将MovementsRow类更改为具有四个Model属性和四个modelid fk然后使用InverseProperty属性吗?

2 个答案:

答案 0 :(得分:0)

MovementsRow.Model属于TwoVariableDetails中的四个集合之外的另一种关系。这就是为什么数据库表中没有四个,而是五个外键的原因。当您将twoVariableDetails插入数据库并且其中一个集合中包含MovementRow实例时,EF期望其ModelId设置为引用现有TwoVariableDetails行的Guid - 它显然没有。因此例外。

  

我应该将MovementsRow类更改为具有四个Model属性   和四个modelid fk然后使用InverseProperty属性?

我会说是的。这可能是最好的解决方案。另一种方法是在Model中完全没有MovementRow属性。它正常运行,但您无法从MovementRow导航到TwoVariableDetails

答案 1 :(得分:0)

您的FK_dbo.Movement_dbo.TwoVariableDetails_ModelId受到了侵犯,只是简单地说,ModelIdMovement记录正在使用的TwoVariableDetails

如果您想保持简单和事务性,那么您可以将TransactionScope与数据库上下文一起使用,首先将TwoVariableDetails保存在事务中,然后再将相关的记录保存到事务中:

using (var context = new MyDbContext())
using (var tranScope = new TransactionScope(TransactionScopeOption.Required) {
  // don't save the Movement records yet
  twoVariableDetails.TwoVariableDetailsId = Guid.NewGuid();
  _context.TwoVariableDetailsModels.Add(twoVariableDetails);
  _context.SaveChanges();

 // now create the movement records, add them to twoVariableDetails
  ...
  _context.SaveChanges();

 // commit the transaction
 scope.Complete();
}