[英]Entity Framework OneToMany updating items - Missing foreign-key value
我想要在配置之前制作的一对多 rel
public class Report
{
[Key]
public string ProtId { get; set; }
public Assessment Assessments { get; set; }
public ManualReview ManualReview {get; set;}
public ICollection<Meeting> Meetings {get; set;}
}
public class Meeting
{
[Key]
public Guid MeetId{get;set;}
public MeetingType? MeetingType { get; set; }
public DateTime? Date { get; set; }
public string ProtId { get; set; }
public Report Report{ get; set; }
}
我想添加新会议,如果它没有被 MeetId 找到,或者更新是用下面的代码找到了 MeetId,但是当我添加新会议时,它会像在这种方法中一样添加到表格中,我认为那里有问题,我的意思是我没有得到参考父表是报告表,因此添加新会议后 ReportProtId 为空。
此外,当我进行迁移时,它正在创建这个
migrationBuilder.CreateTable(
name: "Meetings",
columns: table => new
{
MeetId = table.Column<Guid>(nullable: false),
MeetingType = table.Column<int>(nullable: true),
Date = table.Column<DateTime>(nullable: true),
ProtId= table.Column<string>(nullable: true),
ReportProtId = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Meetings", x => x.MeetId);
table.ForeignKey(
name: "FK_Meetings_Report_ReportProtId",
column: x => x.ReportProtId,
principalTable: "Studies",
principalColumn: "ProtId",
onDelete: ReferentialAction.Restrict);
});
添加/更新会议的方法
[HttpPut ("meetings/{id}")]
public async Task<IActionResult> UpdateMeetings (string id, [FromBody] Meeting data)
{
var meeting = await _liteContext.Meetings.FirstOrDefaultAsync (m => m.MeetId == data.MeetId);
if (meeting == null) {
var newMeeting = new Meeting {
MeetId = new Guid (),
MeetingType = data.MeetingType ?? null,
Date = data.Date ?? null,
};
_liteContext.Meetings.Add (newMeeting);
}
if (meeting != null) {
meeting.MeetingType = data.MeetingType;
meeting.Date = data.Date;
_liteContext.Meetings.Update (meeting);
}
try {
await _liteContext.SaveChangesAsync ();
return NoContent ();
} catch (DbUpdateConcurrencyException) {
throw new Exception ();
}
}
已编辑
[HttpGet("lite")]
public async Task<dynamic> GetData()
{
try
{
var data = await _liteContext.Reports
.Include(a => a.Assessments)
.Include(m => m.Meetings) // empty array
.Include(mr => mr.ManualReview)
.ToListAsync();
return data;
}
catch (System.Exception)
{
throw;
}
}
Meetings 表中的 ReportProtId 列可以为空,并且在添加新会议时的 UpdateMeetings 方法中,您仅将 MeetId、MeetingType 和日期分配给 newMeeting 对象,并且添加时您的 ReportProtId 为空。 像这样将 ReportProtId 分配给 newMeeting 对象:
if (meeting == null) {
var newMeeting = new Meeting {
MeetId = new Guid (),
MeetingType = data.MeetingType ?? null,
Date = data.Date ?? null,
ReportProtId = data.ReportProtId
};
_liteContext.Meetings.Add (newMeeting);
}
创建新会议时,设置ProtId
值 -
var newMeeting = new Meeting {
MeetId = new Guid (),
MeetingType = data.MeetingType ?? null,
Date = data.Date ?? null,
// Add this one
ProtId = data.ProtId
};
我希望你能从客户那里收到它。
编辑 :
根据您的迁移代码, Meetings
表有两列ProtId
和ReportProtId
。 但是您的Meeting
模型类定义仅显示ProtId
属性。
如果您在Meeting
类中有ReportProtId
属性,请设置该属性的值(不是ProtId
),因为您已将ReportProtId
列定义为外键,而不是ProtId
。
如果Meeting
类实际上没有ReportProtId
属性,那么您需要更新迁移代码并相应地更新数据库。
编辑-2:
如果你还没有在定义的配置为你的模型类OnModelCreating
你的方法DbContext
类,则迁移将使用实体框架的默认命名约定生成的表和列。
根据命名约定,您的Meeting
类中的外键属性应命名为ReportId
。 由于实体框架没有找到该属性,它生成了一个供您用作外键 -
Referenced class name (Report) + Primary-key name of referenced class (ProtId) = ReportProtId
这就是您最终在迁移代码中(因此在数据库中)拥有ReportProtId
列的方式,即使您的模型类中没有该属性。
如果需要,您仍然可以使用ProtId
作为外键,但是您必须让实体框架知道您实际上希望该属性作为外键,即使不符合命名约定。 您可以通过向其添加[ForeignKey("Report")]
属性来做到这一点。
因此,将您的Meeting
类定义更改为 -
public class Meeting
{
[Key]
public Guid MeetId{get;set;}
public MeetingType? MeetingType { get; set; }
public DateTime? Date { get; set; }
public string ReprotId { get; set; } // Modified
public Report Report{ get; set; }
}
或者 -
// this import will be required
// using System.ComponentModel.DataAnnotations.Schema;
public class Meeting
{
[Key]
public Guid MeetId { get; set; }
public string MeetingType { get; set; }
public DateTime? Date { get; set; }
[ForeignKey("Report")] // Added
public string ProtId { get; set; }
public Report Report { get; set; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.