I have the following three related entity classes:
public class ContextInstance { public Int64 Id { get; set; } public virtual List<ContextParamValue> ContextParamValues { get; set; } } public class ContextParamValue { public Int64 Id { get; set; } public virtual Int64 ContextParamId { get; set; } public virtual ContextParam ContextParam { get; set; } public virtual ContextInstance ContextInstance { get; set; } public virtual Int64 ContextInstanceId { get; set; } public string Value { get; set; } } public class ContextParam { public Int64 Id { get; set; } [Required] public string Name { get; set; } [DefaultValue("")] public string Description { get; set; } }
I established a loose relationship as follows:
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>(); modelBuilder.Entity<ContextInstance>() .HasMany(ci => ci.ContextParamValues) .WithRequired(cpv => cpv.ContextInstance) .HasForeignKey(cpv => cpv.ContextInstanceId) .WillCascadeOnDelete(true);
I have the following Helper class, the ParamValueToList method of which periodically throws an exception using a NULL reference:
public class RuntimeHelper : IDisposable { DocumentDbContext db; ConfigurationHelper ch; private RuntimeHelper() { } public RuntimeHelper(DocumentDbContext context) { db = context; ch = new ConfigurationHelper(context); } public List<ContextParamValue> ParamValuesToList(string[] ParamNames, string[] ParamValues) { Trace.TraceInformation("-- ParamValuesToList invoked --"); if (ParamNames != null && ParamNames.Length != ParamValues.Length) throw new System.ArgumentException("ParamNames and ParamValues may not differ in length."); Dictionary<string, string> d = new Dictionary<string, string>(); for (int i = 0; i < ParamNames.Length; i++) { string pName = ParamNames[i]; string pValue = ParamValues[i]; d.Add(pName, pValue); Trace.TraceInformation("ParamValuesToList Key: " + pName + "; Value: " + pValue + ";"); } Trace.TraceInformation("Value of db:" + db.ContextParamValues.ToString()); var cpvList = db.ContextParamValues .Include(x => x.ContextParam) .ToArray<ContextParamValue>(); List<ContextParamValue> lst = cpvList .Where(pv => d.Contains(new KeyValuePair<string, string>(pv.ContextParam.Name, pv.Value)))
The specific operator from the above method, which throws an error,
List<ContextParamValue> lst = cpvList .Where(pv => d.Contains(new KeyValuePair<string, string>(pv.ContextParam.Name, pv.Value))) .ToList<ContextParamValue>();
A null reference exception is NOT thrown under the following condition:
- Only 1 ContextParamValue exists for this ContextInstance
- Example: ContextParamValue.ContextParam.Name = "ClientId" and ContextParamValue1.Value = "1"
The null reference exception refers to the following condition:
- For this ContextInstance, there are two or more ContextParamValues
- Example: ContextParamValue1.ContextParam.Name = "ClientId" and ContextParamValue1.Value = "1" PLUS ContextParamValue2.ContextParam.Name = "MotivationId" and ContextParamValue2.Value = "1".
I can confirm the following about the helper method in question:
- d is not null and does not contain any keys with null values
- cpvList is not null and is not empty when an error occurs.
- ContextParam does not load ContextParamValue for parent objects in all cases (it is loaded only for the first instance of ContextParamValue, but only zero value is loaded for subsequent instances).
- There are no null ContextParam entries in the database ... All ContextParamValues โโhave one ContextParam entry.
During execution, the following trace and stack information is generated:
Application: 2014-05-16T19: 00: 20 PID [4800] Error System.NullReferenceException: the reference to the object is not installed in the object instance. Usage: with DocumentManagement.Helpers.RuntimeHelper <. > C__DisplayClass28.b__27 (ContextParamValue pv) in c: \ Users \ xxx \ Dropbox \ xxx \ Active Projects \ xxx \ DocumentManagement \ Helpers \ DocsHelper_RT.cs: line 229 Application: in System.Linq.Enumerable.WhereArrayIterator1.MoveNext () : in System.Collections.Generic.List1..ctor (IEnumerable1 collection) Application: with System.Linq.Enumerable.ToList [TSource] (source IEnumerable1) Application: with DocumentManagement.Helpers.RuntimeHelper.ParamValuesToList (String [] ParamNames, String [] ParamValues) in c: \ Users \ xxx \ Dropbox \ xxx \ Active Projects \ xxx \ DocumentManagement \ Helpers \ DocsHelper_RT.cs: line 228 Application: with DocumentManagement.Helpers.RuntimeHelper.GetContextInstances (String [] ParamNames, String [] ParamValues, Boolean AsNoTracking) in C: \ Users \ xxx \ Dropbox \ xxx \ Active Projects \ xxx \ DocumentManagement \ Helpers \ DocsHelper_RT.cs: line 262 Appendix: in xx x.Controllers.ClientController.LoadStep2 (Int64 ClientId, String Error) in c: \ Users \ xxx \ Dropbox \ xxx \ Active Projects \ xxx \ xxx \ Views \ Client \ ClientController.cs: line 198

