Sql server 如何处理一对多关系中的可选外键约束错误
我是一名ASP.NETMVC5的初学者,目前仍在处理FLUENTAPI问题。我有一个推荐类,它可以和求职信类有一对多的关系。有时,可能存在一个没有封面信的重新勘误的行(我认为是0..*) 流畅的API:Sql server 如何处理一对多关系中的可选外键约束错误,sql-server,asp.net-mvc,entity-framework,asp.net-mvc-5,ef-fluent-api,Sql Server,Asp.net Mvc,Entity Framework,Asp.net Mvc 5,Ef Fluent Api,我是一名ASP.NETMVC5的初学者,目前仍在处理FLUENTAPI问题。我有一个推荐类,它可以和求职信类有一对多的关系。有时,可能存在一个没有封面信的重新勘误的行(我认为是0..*) 流畅的API: //// one cover letter can be there in many referral request dBModelBuilder.Entity<CoverLetter>() .HasMany(u => u.Referrals) .WithOp
//// one cover letter can be there in many referral request
dBModelBuilder.Entity<CoverLetter>()
.HasMany(u => u.Referrals)
.WithOptional(u => u.CoverLetter)
.HasForeignKey(u => u.CoverLetterId);
public class Referral
{
[Key]
public int ReferralId { get; set; }
// I added "?" to make FK Optional
public int? CoverLetterId { get; set; }
public virtual CoverLetter CoverLetter { get; set; }
}
public class ReferralViewModel
{
public int ReferralViewModelId { get; set; }
[Display(Name = "Cover Letter")]
public int CoverLetterId { get; set; }
public IEnumerable<CoverLetter> CoverLetters { get; set; }
}
[HttpPost]
public ActionResult Create(ReferralViewModel viewModel)
{
var candidateId = User.Identity.GetUserId();
var referral = new Referral
{
CoverLetterId = viewModel.CoverLetterId
};
// I get exception here
_context.Referrals.Add(referral);
_context.SaveChanges();
return RedirectToAction("ReferralCenter");
}
参考视图模型:
//// one cover letter can be there in many referral request
dBModelBuilder.Entity<CoverLetter>()
.HasMany(u => u.Referrals)
.WithOptional(u => u.CoverLetter)
.HasForeignKey(u => u.CoverLetterId);
public class Referral
{
[Key]
public int ReferralId { get; set; }
// I added "?" to make FK Optional
public int? CoverLetterId { get; set; }
public virtual CoverLetter CoverLetter { get; set; }
}
public class ReferralViewModel
{
public int ReferralViewModelId { get; set; }
[Display(Name = "Cover Letter")]
public int CoverLetterId { get; set; }
public IEnumerable<CoverLetter> CoverLetters { get; set; }
}
[HttpPost]
public ActionResult Create(ReferralViewModel viewModel)
{
var candidateId = User.Identity.GetUserId();
var referral = new Referral
{
CoverLetterId = viewModel.CoverLetterId
};
// I get exception here
_context.Referrals.Add(referral);
_context.SaveChanges();
return RedirectToAction("ReferralCenter");
}
问题
如果我没有从UI中选择任何封面信,则封面信ID在我的viewModel中为0。我想因为在DB中没有ID为0的求职信,所以我得到了DB合同例外
例外情况:
{“INSERT语句与外键约束冲突
\“FK_dbo.references_dbo.CoverLetters_CoverLetterId\”。冲突
在数据库“aspnet-Bridge-20170730012232”的表中发生
\“dbo.CoverLetters\”列中的“CoverLetterId”。\r\n该语句具有
已被终止。”}
要使FK可选,我执行了两个步骤
a。在模型属性中添加了“?”
b。在Fluent API中添加了“HasOptional”
修正:
如果我没有选择任何封面,那么在提交表格时,我希望封面ID为NULL而不是零。更改控制器中的封面ID分配
CoverLetterId = viewModel.CoverLetterId == 0 ? null : viewModel.CoverLetterId;
或
你也可以
public int CoverLetterId { get; set; }
改为
公共int?CoverlettId{get;set;}位于ReferralViewModel
中
然后,在控制器中,您必须使用附加检查
CoverLetterId = viewModel.CoverLetterId.HasValue ? ((viewModel.CoverLetterId.Value == 0) ? null : viewModel.CoverLetterId.Value) : null
如果您知道要在HttpPost中从前端传递0,并且不让viewModel.CoverlettId接受其默认值,则可以使用
CoverLetterId = (viewModel.CoverLetterId.Value == 0) ? null : viewModel.CoverLetterId.Value
更改控制器中的求职信id分配
CoverLetterId = viewModel.CoverLetterId == 0 ? null : viewModel.CoverLetterId;
或
你也可以
public int CoverLetterId { get; set; }
改为
公共int?CoverlettId{get;set;}位于ReferralViewModel
中
然后,在控制器中,您必须使用附加检查
CoverLetterId = viewModel.CoverLetterId.HasValue ? ((viewModel.CoverLetterId.Value == 0) ? null : viewModel.CoverLetterId.Value) : null
如果您知道要在HttpPost中从前端传递0,并且不让viewModel.CoverlettId接受其默认值,则可以使用
CoverLetterId = (viewModel.CoverLetterId.Value == 0) ? null : viewModel.CoverLetterId.Value
视图模型中的
CoverLetterId
属性需要是int?
(可为空)@StephenMuecke:Sir,如果它是字符串,那么我不必添加“?”right?,因为字符串不会自动初始化为“空字符串”,它们保留空值。但在整数的情况下,它们默认自动初始化为0。字符串
已经可以为空,所以您无需执行任何操作。但是因为它是int
你需要做它nullable@StephenMuecke这消除了我的疑虑。因为在另外一个地方,我有一个可选的FK关系,而且一直都很好。我刚才查过了。它是字符串类型的“applicationSerid”(由框架提供),因此不需要“?”。)视图模型中的CoverLetterId
属性需要是int?
(可为空)@StephenMuecke:Sir,如果它是字符串,那么我不必添加“?”right?,因为字符串不会自动初始化为“空字符串”,它们保留空值。但在整数的情况下,它们默认自动初始化为0。字符串
已经可以为空,所以您无需执行任何操作。但是因为它是int
你需要做它nullable@StephenMuecke这消除了我的疑虑。因为在另外一个地方,我有一个可选的FK关系,而且一直都很好。我刚才查过了。它是字符串类型的“applicationSerid”(由框架提供),因此不需要“?”。)您不需要在最后一行代码中进行“附加检查”!它不会是“0”(除非是恶意用户),因此没有point@Stephen好的,明白了。但网站确实有恶意用户。通过合并您的注释,在回答中添加了一条语句。是的,如果您不想使用恶意用户,则保存数据(引发异常):)您不需要在最后一行代码中进行“附加检查”!它不会是“0”(除非是恶意用户),因此没有point@Stephen好的,明白了。但网站确实有恶意用户。在回答中添加了一条语句,但加入了您的注释。是的,如果您不想使用恶意用户,请保存数据(引发异常):)