当我指定一个 hasMany 关系时违反了多重约束
Multiplicity constraint violated when I specified a hasMany relation
我正在使用 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; }
}
然后在 Entity Framework 中,我告诉框架使用代码优先保存这些 类:
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 行。 Entity Framework 然后开始吐出异常:
Multiplicity constraint violated. The role 'ReportRow_ReportCells_Source' of the relationship 'Persistance.ReportRow_ReportCells' has multiplicity 1 or 0..1.
(我已经查看了之前提出的所有可用问题,但到目前为止还没有找到满意的答案...)
错误的奇怪之处在于我在 Report
和 ReportRow
之间使用了 hasMany()
并且工作正常。但同样的事情在 ReportRow
和 ReportCell
之间不起作用?我真的希望我只是遗漏了一些非常简单的东西,我已经在这上面浪费了一天...
解决方案已由 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);
}
我正在使用 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; }
}
然后在 Entity Framework 中,我告诉框架使用代码优先保存这些 类:
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 行。 Entity Framework 然后开始吐出异常:
Multiplicity constraint violated. The role 'ReportRow_ReportCells_Source' of the relationship 'Persistance.ReportRow_ReportCells' has multiplicity 1 or 0..1.
(我已经查看了之前提出的所有可用问题,但到目前为止还没有找到满意的答案...)
错误的奇怪之处在于我在 Report
和 ReportRow
之间使用了 hasMany()
并且工作正常。但同样的事情在 ReportRow
和 ReportCell
之间不起作用?我真的希望我只是遗漏了一些非常简单的东西,我已经在这上面浪费了一天...
解决方案已由 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);
}