MVC4 EF插入父项如果不存在,那么孩子

时间:2016-05-17 16:14:48

标签: entity-framework asp.net-mvc-4

我的桌子有这种关系。 Activity, Workstation, Platform, Part是查找表。

我的ActivitWorkstation包含ActivityWorkstation表的(ActivityId,WorkstationId)外键。

我还有PlatformPart包含({1}}和Platform表的(PlatformId,PartId)外键。

最后,我有Part表,其中包含(PartStagingActivityWorkstation个表的(ActivityWorkstationId,PlatformPartId)外键。

在我的PartStaging控制器中,在Create方法中,用户将从下拉列表中选择一个Activity,Workstation,Platform和Part。

在我的PartStaging控制器中,在HttpPost Create方法中,它应该检查ActivityWorkstation和PlatformPart记录是否存在。如果没有,插入它们,然后插入PartStaging记录。以下是我的代码:

PlatformPart

我收到此错误:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(PartStagingVM partstagingvm)
{
    if (ModelState.IsValid)
    {
        PartStaging partstaging = new PartStaging();

        if(!db.ActivityWorkstations.Any(aw => aw.ActivityId == partstagingvm.ActivityId && aw.WorkstationId == partstagingvm.WorkstationId))
        {
            ActivityWorkstation aw = new ActivityWorkstation();

            aw.ActivityId = partstagingvm.ActivityId;
            aw.WorkstationId = partstagingvm.WorkstationId;

            db.ActivityWorkstations.Add(aw);
            db.Entry(aw).State = EntityState.Added;
        }

        if(!db.PlatformParts.Any(pp => pp.PlatformId == partstagingvm.PlatformId && pp.PartId == partstagingvm.PartId))
        {
            PlatformPart pp = new PlatformPart();

            pp.PlatformId = partstagingvm.PlatformId;
            pp.PartId = partstagingvm.PartId;

            db.PlatformParts.Add(pp);
            db.Entry(pp).State = EntityState.Added;
        }

        var activityWorkstationId = db.ActivityWorkstations.Where(aw => aw.ActivityId == partstagingvm.ActivityId && aw.WorkstationId == partstagingvm.WorkstationId).FirstOrDefault().Id;
        var platformPartId = db.PlatformParts.Where(pp => pp.PlatformId == partstagingvm.PlatformId && pp.PartId == partstagingvm.PartId).FirstOrDefault().Id;

        partstaging.ActivityWorkstationId = activityWorkstationId;
        partstaging.PlatformPartId = platformPartId;

        db.PartStagings.Add(partstaging);
        db.SaveChanges();
    }

    return View(partstagingvm);
}

我知道这是由父记录(Object reference not set to an instance of an object. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.NullReferenceException: Object reference not set to an instance of an object. Source Error: Line 243: } Line 244: Line 245: var activityWorkstationId = db.ActivityWorkstations.Where(aw => aw.ActivityId == partstagingvm.ActivityId && aw.WorkstationId == partstagingvm.WorkstationId).FirstOrDefault().Id; Line 246: var platformPartId = db.PlatformParts.Where(pp => pp.PlatformId == partstagingvm.PlatformId && pp.PartId == partstagingvm.PartId).FirstOrDefault().Id; Line 247: 和/或ActivityWorkstation记录)不存在引起的。

如何在插入PlatformPart之前插入父记录?

1 个答案:

答案 0 :(得分:1)

您无需获取外键,因为Entity Framework非常智能,可以为您提供连接。所以去获取导航属性,如果它不存在则创建它。假设您在PartStaging上有适当的导航属性,请执行以下操作:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(PartStagingVM partstagingvm)
{
    if (ModelState.IsValid)
    {
        var activityWS = db.ActivityWorkstations
                           .FirstOrDefault(aw => aw.ActivityId == partstagingvm.ActivityId 
                                                 && aw.WorkstationId == partstagingvm.WorkstationId);
        if (activityWS == null)
        {
            // If we get here EF will add this item, otherwise uses the found version
            activityWS = new ActivityWorkstation 
                         {
                             partstagingvm.ActivityId,
                             partstagingvm.WorkstationId
                         };
        }

        var platformPart= db.PlatformParts
                            .FirstOrDefault(pp => pp.PlatformId == partstagingvm.PlatformId 
                                                  && pp.PartId == partstagingvm.PartId);

        if (platformPart == null)
        {
            platformPart = new PlatformPart
                           {
                               partstagingvm.PlatformId,
                               partstagingvm.PartId
                           };
        }

        PartStaging partstaging = new PartStaging
                                  {
                                       ActivityWorkstation = activityWS,  // Set navigation property
                                       PlatformPart = platformPart
                                  };

        db.PartStagings.Add(partstaging);
        db.SaveChanges();
    }

    return View(partstagingvm);
}