当我指定hasMany关系时违反了多重约束

时间:2015-01-15 11:16:32

标签: c# entity-framework asp.net-mvc-5 ef-migrations

我正在使用Entity Framework在一个ReportCell对象中保存对象列表(ReportRow)。然后,多个ReportRow个对象保留在一个报告中。

这些课程如下:

报告

public class Report
{
    public int ReportId { get; set; }
    public virtual List<ReportRow> ReportRows { get; set; }

    public Report()
    {            
        ReportRows = new List<ReportRow>();
    }
}

ReportRow

public class ReportRow
{
    public int ReportRowId { get; set; }
    public virtual List<ReportCell> ReportCells { get; set; }

    public ReportRow()
    {
        ReportCells = new List<ReportCell>();
    }
}

ReportCell

public class ReportCell
{
    public int ReportCellId { get; set; }
    public string Data { get; set; }
}

然后在实体框架中,我告诉框架使用Code First持久化这些类:

modelBuilder.Entity<Report>().HasKey(r => r.ReportId);
modelBuilder.Entity<Report>()
            .Property(r => r.ReportId)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Report>().HasMany(rep => rep.ReportRows);

modelBuilder.Entity<ReportRow>().HasKey(rr => rr.ReportRowId);
modelBuilder.Entity<ReportRow>()
            .Property(rr => rr.ReportRowId)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<ReportRow>().HasMany(rr => rr.ReportCells);

modelBuilder.Entity<ReportCell>().HasKey(rc => rc.ReportCellId);
modelBuilder.Entity<ReportCell>()
            .Property(rc => rc.ReportCellId)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<ReportCell>().Property(rc => rc.Data);

我有一个广泛的数据库种子,在成功迁移后填充数据库,因为Entity Framework每次迁移都会设法丢弃我的所有数据(AutomaticDataLossAllowed = true)。 执行下一个代码时,我在SaveChanges()

上得到一个例外
protected override void Seed(ReportModuleContext context)
{
    var cells = new List<ReportCell>();
    for (var n = 1; n <= 100; n++)
    {
           cells.Add(new ReportCell { Data = "Random data " + n, ReportCellId = n});
    }

    var rows = new List<ReportRow>();
    for (var x = 0; x < 20; x++)
    {
        var row = new ReportRow();
        row.ReportCells.Add(cells[x]);
        row.ReportCells.Add(cells[x+1]);
        row.ReportCells.Add(cells[x+2]);
        row.ReportCells.Add(cells[x+3]);
        row.ReportCells.Add(cells[x+4]);
        row.ReportRowId = x;
        rows.Add(row);
    }

    IList<Report> reports = new List<Report>();
    reports.Add(new Report
    {
        ReportId = 1,
        ReportRows = rows
    });
    reports.Add(new Report
    {
        ReportId = 2,
        ReportRows = rows
    });
    foreach (var rep in reports)
    {
        context.Reports.AddOrUpdate(rep);
    }
    context.SaveChanges();
}

所以它所做的就是制作一些字符串,将它们用作Data并在每行中添加5个单元格。然后在报表中添加5行。然后,实体框架开始吐出异常:

  

违反了多重性约束。角色&#39; ReportRow_ReportCells_Source&#39;关系&Persidence.ReportRow_ReportCells&#39;具有多重性1或0..1。

(我已经查看了之前提出的所有可用问题,但尚未找到令人满意的答案......)

关于错误的奇怪之处在于我在hasMany()Report之间使用了ReportRow,这很好用。但同样的事情在ReportRowReportCell之间不起作用?我真的希望我错过了一些非常简单的事情,我已经失去了一天......

1 个答案:

答案 0 :(得分:0)

Damien_The_Unbeliever提供了解决方案。

当在2个不同的对象中使用相同的对象时,实体框架开始给出麻烦(我知道)。 for循环中的一个小错误导致对象被多次使用。修复循环完全解决了这个问题。

固定代码如下:

var rows = new List<ReportRow>();
for (var x = 0; x < 20; x+=5)
{
    var row = new ReportRow();
    row.ReportCells.Add(cells[x]);
    row.ReportCells.Add(cells[x+1]);
    row.ReportCells.Add(cells[x+2]);
    row.ReportCells.Add(cells[x+3]);
    row.ReportCells.Add(cells[x+4]);
    row.ReportRowId = x;
    rows.Add(row);
}