Related table data not saved on call to SaveChangesAsync

paul carron 1 Reputation point
2021-05-01T13:03:24.443+00:00

I have these entities in my C# application:

public class Balance1 : IAnalyticsSection
{
    public int Id { get; set; }
    public Guid DataFileId { get; set; }

    public string Side { get; set; }
    public decimal AverageHeadSway { get; set; }
    public decimal AverageSwaySpeed { get; set; }
    public decimal AverageLHandSway { get; set; }
    public decimal AverageRHandSway { get; set; }
    public decimal PercentAverageInLeftSphere { get; set; }
    public decimal PercentAverageInRightSphere { get; set; }
    public decimal AverageTotalSway { get; set; }

    public virtual ICollection<Balance1Part> Parts { get; set; } = new List<Balance1Part>();
    public virtual DataFile DataFile { get; set; }
}

public class Balance1Part
{
    public int Id { get; set; }
    public int Balance1Id { get; set; }

    public int Order { get; set; }
    public decimal ConvexHullArea { get; set; }
    public decimal HeadSway { get; set; }
    public decimal SwaySpeed { get; set; }
    public decimal LeftHandSway { get; set; }
    public decimal RightHandSway { get; set; }
    public decimal PercentInLeftSphere { get; set; }
    public decimal PercentInRightSphere { get; set; }
    public decimal TotalSway { get; set; }

    public virtual Balance1 Balance1 { get; set; }
}

I also have this service:

if (((values["DataType"]).Equals("Balance1R")) || ((values["DataType"]).Equals("Balance1L")))
{
    var innerBalance1File = innerContext.Balance1.SingleOrDefaultAsync(x => x.DataFileId == dataFile.Id).Result;
    Balance1Class balance1Class = new Balance1Class();

    balance1Class.Balance1Data(innerBalance1File, values);
    innerContext.Entry(innerBalance1File).State = EntityState.Added;
    innerContext.SaveChangesAsync().Wait();
}

This is my

public class Balance1Class
{
    public Balance1 Balance1Data(Balance1 balance1, Dictionary<string, object> values)
    {
        Balance1Part balance1Part = new Balance1Part();

        if ((values["DataType"]).Equals("Balance1R"))
        {
            balance1.Side = "R";
        }
        else
        {
            balance1.Side = "L";
        }

        balance1.AverageHeadSway = decimal.Parse(values["AverageHeadSway"].ToString());
        balance1.AverageLHandSway = decimal.Parse(values["AverageLHandSway"].ToString());
        balance1.AverageRHandSway = decimal.Parse(values["AverageRHandSway"].ToString());
        balance1.AverageSwaySpeed = decimal.Parse(values["AverageSwaySpeed"].ToString());
        balance1.AverageTotalSway = decimal.Parse(values["AverageTotalSway"].ToString());
        balance1.PercentAverageInLeftSphere = decimal.Parse(values["%AverageInLeftSphere"].ToString());
        balance1.PercentAverageInRightSphere = decimal.Parse(values["%AverageInRightSphere"].ToString());

       for (int i = 1; i < 6; i++)
       {
           Balance1Part balance1Part = new Balance1Part();
           balance1Part.HeadSway = decimal.Parse(values["HeadSway" + i].ToString());
           balance1Part.SwaySpeeds = decimal.Parse(values["SwaySpeeds" + i].ToString());
           balance1Part.LeftHandSway = decimal.Parse(values["LeftHandSway" + i].ToString());
           balance1Part.RightHandSway = decimal.Parse(values["RightHandSway" + i].ToString());
           balance1Part.PercentInLeftSphere = decimal.Parse(values["%InLeftSphere" + i].ToString());
           balance1Part.PercentInRightSphere = decimal.Parse(values["%InRightSphere" + i].ToString());
           balance1Part.TotalSway = decimal.Parse(values["TotalSway" + i].ToString());
           balance1Part.ConvexHullArea = decimal.Parse(values["ConvexHullArea" + i].ToString());
           balance1Part.Order = i;
           balance1.Parts.Add(balance1Part);
       }

       return balance1;
    }
}

When I run my application I get this error:

021-04-26 08:13:09.953 +00:00 [Error] VR.Api.Server.Services.CalculationService: DataFile 2862a31f-56c0-4e48-96ad-f7d95888ca8f metrics calculation failed.System.NullReferenceException: Object reference not set to an instance of an object.at VR.API.Server.Balance1Class.Balance1Data(Balance1 balance1, Dictionary`2 values) in D:\Repos\VR.API\VR.API.Server\Services\Balance1Class.cs:line 23at VR.Api.Server.Services.CalculationService.CalculateMetricsAsync(DataFile dataFile, VRContext innerContext) in D:\Repos\VR.API\VR.API.Server\Services\CalculationService.cs:line 93

I think the problem is that var innerBalance1File = innerContext.Balance1.SingleOrDefaultAsync(x => x.DataFileId == dataFile.Id).Result; could be null as x.DataFileId may not yet exist. I believe the first part of my query is around how I should deal with this or if there's some different way I should construct this?

If I create a new balance1 object and pass it to Balance1Data it returns balance1 with balance1Part included but this never gets added to the db. I believe there's something like innerContext.ADD(balance1); missing. Can anybody please confirm?

FYI this is a sample json:

{"DataType": "Balance1L", "ConvexHullArea1": 15.405972157118612, "ConvexHullArea2": 8.57073817402744, "ConvexHullArea3": 26.043312818568893, "ConvexHullArea4": 8.073813118246733, "ConvexHullArea5": 1.4146644620183224, "HeadSway1": 0.14077433925381086, "HeadSway2": 0.11729374795881226, "HeadSway3": 0.11115592906874093, "HeadSway4": 0.17934800924384686, "HeadSway5": 0.14058627677904187, "SwaySpeeds1": 0.014049279789085, "SwaySpeeds2": 0.011729107456491224, "SwaySpeeds3": 0.011115338496965868, "SwaySpeeds4": 0.017934390438763683, "SwaySpeeds5": 0.014114764968692298, "LeftHandSway1": 0.10186321482949473, "LeftHandSway2": 0.1016288555261327, "LeftHandSway3": 0.1011778983984107, "LeftHandSway4": 0.14205440756223064, "LeftHandSway5": 0.1252705623268904, "RightHandSway1": 0.091226741386216, "RightHandSway2": 0.09966321375829411, "RightHandSway3": 0.09800499347200739, "RightHandSway4": 0.13937686240007166, "RightHandSway5": 0.11648152406566481, "%InLeftSphere1": 99.800796812749, "%InLeftSphere2": 99.8003992015968, "%InLeftSphere3": 99.8003992015968, "%InLeftSphere4": 99.8003992015968, "%InLeftSphere5": 99.8, "%InRightSphere1": 99.800796812749, "%InRightSphere2": 99.8003992015968, "%InRightSphere3": 99.8003992015968, "%InRightSphere4": 99.8003992015968, "%InRightSphere5": 99.8, "AverageHeadSway": 0.13783166046085055, "AverageSwaySpeed": 0.013788576229999613, "AverageLHandSway": 0.11439898772863184, "AverageRHandSway": 0.1089506670164508, "%AverageInLeftSphere": 99.80039888350788, "%AverageInRightSphere": 99.80039888350788, "TotalSway1": 0.23731931736166623, "TotalSway2": 0.21793978260102564, "TotalSway3": 0.21074737500394997, "TotalSway4": 0.320063644224998, "TotalSway5": 0.2614623199753195, "AverageTotalSway": 0.24950648783339185}
Entity Framework Core
Entity Framework Core
A lightweight, extensible, open-source, and cross-platform version of the Entity Framework data access technology.
743 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,962 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Karen Payne MVP 35,426 Reputation points
    2021-05-01T15:11:37.603+00:00

    Have you tried

    var innerBalance1File = await innerContext.Balance1.SingleOrDefaultAsync(x => x.DataFileId == dataFile.Id);
    

    Also, other things to try, creating a unit test and feed good data in one test than another test invalid data and assert.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.