question

paulcarron-8869 avatar image
0 Votes"
paulcarron-8869 asked DuaneArnold-0443 commented

Related table data not saved on call to SaveChangesAsync


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}





dotnet-csharpdotnet-entity-framework-core
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.


To make sure that innerBalance1File is found and not null, you can use Single or SingleAsync instead of SingleOrDefaultAsync.

It is not clear how values and innerContext are related.

Which line is line 23, mentioned in error message?

0 Votes 0 ·

If you were implementing Seperation of Concerns where the service is calling a classlib project like a DAL, then you could have used a test classlib project to test the Json data for persistence using your EF model objects trying to persist the data in a functional test. All kinks would have been ironed out before you tried to use the service.

https://en.wikipedia.org/wiki/Separation_of_concerns

https://docs.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/architectural-principles

0 Votes 0 ·

1 Answer

karenpayneoregon avatar image
0 Votes"
karenpayneoregon answered

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.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.