[英]Entity Framework OneToMany updating items - Missing foreign-key value
I want to have one to many rel which i made with before config我想要在配置之前制作的一对多 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; }
}
I want to add new meeting if it was not found by MeetId or update is MeetId found with below code but when i add new meeting it is added to table like in this method i think something is wrong there i mean i do not get reference to Parent table which is Report table so after adding new meeting ReportProtId is null.我想添加新会议,如果它没有被 MeetId 找到,或者更新是用下面的代码找到了 MeetId,但是当我添加新会议时,它会像在这种方法中一样添加到表格中,我认为那里有问题,我的意思是我没有得到参考父表是报告表,因此添加新会议后 ReportProtId 为空。
Also when i make migration it is creating this此外,当我进行迁移时,它正在创建这个
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);
});
Method to add/update meetings添加/更新会议的方法
[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 ();
}
}
EDITED已编辑
[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;
}
}
ReportProtId column in Meetings table is nullable and in your UpdateMeetings method while adding a new Meeting you are only assigning MeetId, MeetingType, and Date to newMeeting object and your ReportProtId is null while adding. Meetings 表中的 ReportProtId 列可以为空,并且在添加新会议时的 UpdateMeetings 方法中,您仅将 MeetId、MeetingType 和日期分配给 newMeeting 对象,并且添加时您的 ReportProtId 为空。 Assign ReportProtId to newMeeting object like this:
像这样将 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);
}
When creating new Meeting, set the ProtId
value -创建新会议时,设置
ProtId
值 -
var newMeeting = new Meeting {
MeetId = new Guid (),
MeetingType = data.MeetingType ?? null,
Date = data.Date ?? null,
// Add this one
ProtId = data.ProtId
};
I hope you are receiving it from the client.我希望你能从客户那里收到它。
Edit :编辑 :
According to your migration code, the Meetings
table has two columns ProtId
and ReportProtId
.根据您的迁移代码,
Meetings
表有两列ProtId
和ReportProtId
。 But your model class definition for Meeting
shows only the ProtId
property.但是您的
Meeting
模型类定义仅显示ProtId
属性。
If you do have a ReportProtId
property in Meeting
class, set the value for that property (not for ProtId
) since you have defined ReportProtId
column as the foreign-key, not ProtId
.如果您在
Meeting
类中有ReportProtId
属性,请设置该属性的值(不是ProtId
),因为您已将ReportProtId
列定义为外键,而不是ProtId
。
If the Meeting
class in fact doesn't have the ReportProtId
property then you need to update your Migration code and update the database accordingly.如果
Meeting
类实际上没有ReportProtId
属性,那么您需要更新迁移代码并相应地更新数据库。
Edit-2 :编辑-2:
If you haven't defined any configuration for your model classes in the OnModelCreating
method of your DbContext
class, then Migration will use Entity Frameworks' default naming convention to generate the tables and columns.如果你还没有在定义的配置为你的模型类
OnModelCreating
你的方法DbContext
类,则迁移将使用实体框架的默认命名约定生成的表和列。
According to the naming convention, the foreign-key property in your Meeting
class should be named ReportId
.根据命名约定,您的
Meeting
类中的外键属性应命名为ReportId
。 Since Entity Framework didn't find that property, it generated one for you to use as foreign-key -由于实体框架没有找到该属性,它生成了一个供您用作外键 -
Referenced class name (Report) + Primary-key name of referenced class (ProtId) = ReportProtId
That's how you ended up having the ReportProtId
column in your Migration code (and hence in the database) even though you don't have that property in your model class.这就是您最终在迁移代码中(因此在数据库中)拥有
ReportProtId
列的方式,即使您的模型类中没有该属性。
You can still use ProtId
as foreign-key if you want, but then you have to let Entity Framework know you in fact want that property as foreign-key, even if doesn't conform to the naming convention.如果需要,您仍然可以使用
ProtId
作为外键,但是您必须让实体框架知道您实际上希望该属性作为外键,即使不符合命名约定。 You can do that by add the [ForeignKey("Report")]
attribute to it.您可以通过向其添加
[ForeignKey("Report")]
属性来做到这一点。
So, change your Meeting
class definition either to -因此,将您的
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; }
}
or to -或者 -
// 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.