[英]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.