Sql server 如何处理一对多关系中的可选外键约束错误

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

我是一名ASP.NETMVC5的初学者,目前仍在处理FLUENTAPI问题。我有一个推荐类,它可以和求职信类有一对多的关系。有时,可能存在一个没有封面信的重新勘误的行(我认为是0..*)

流畅的API:

//// 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好的,明白了。但网站确实有恶意用户。在回答中添加了一条语句,但加入了您的注释。是的,如果您不想使用恶意用户,请保存数据(引发异常):)