Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FirstOrDefault throws NullReferenceException

Given the code:

using (MyContext ctx = new MyContext())
{
    // Returns true:
    var any = ctx.AggregateListAnswers.Any(); 
    // Throws NullReferenceException:
    var fod = ctx.AggregateListAnswers.FirstOrDefault();
}

The line that invokes .FirstOrDefault() throw a NullReferenceException, while the line that calls .Any() returns true.

The mapping for AggregateListAnswer is defined like:

modelBuilder.Entity<AggregateListAnswer>().ToTable("UccAggregate_ListAnswers");

After the initial create, the table is dropped, and an indexed view of the same name is created. There is plenty of data in the view.

What might cause this? How can I troubleshoot the NullReferenceException?

UPDATE

I can work around the issue using a projection on an entity with the same properties, but without the [KeyAttribute] attributes:

var materialized = ctx.Set<AggregateListAnswer>
                      .Select(a => new AggregateListAnswerNoKey()
                      {
                          PropA = a.PropA,
                          PropB = a.PropB
                      }).ToList()

Here is the class, with the method names shortened to obfuscate some domain details:

public class AggregateListAnswer
{
    [Key, Column(Order = 0)]public virtual int? PY { get; set; }
    [Key, Column(Order = 1)]public virtual short? CC { get; set; }
    [Key, Column(Order = 2)]public virtual short? BC { get; set; }
    [Key, Column(Order = 3)]public virtual short? MC { get; set; }
    [Key, Column(Order = 4)]public virtual short? SC { get; set; }
    [Key, Column(Order = 5)]public virtual short? BSC { get; set; }
    [Key, Column(Order = 6)]public virtual short? FTC { get; set; }
    [Key, Column(Order = 7)]public virtual short? MTC { get; set; }
    [Key, Column(Order = 8)]public virtual short? DTC { get; set; }
    [Key, Column(Order = 9)]public virtual int RQId { get; set; }
    [Key, Column(Order = 9)]public virtual Question RQ { get; set; }
    [Key, Column(Order = 10)]public virtual int NumericValue { get; set; }
    [Key, Column(Order = 11)]public virtual short? SeC { get; set; }

    public long Cnt { get; set; }

    public double Wgt { get; set; }
}

Note that Cnt and Wgt are not intended to be persisted. They are transient properties. The key is so large because it corresponds to the columns in an existing indexed view. Two properties are both annotated with the same key order 9 because they are the same thing (the ID and the object the ID refers to).

like image 732
Eric J. Avatar asked Jun 28 '26 15:06

Eric J.


1 Answers

The difference between Any and the projection on the one hand and FirstOrDefault on the other hand is that in the latter case an AggregateListAnswer object is materialized. Any only returns a boolean and the projection some other object. So the NRE must be caused by creating the object. The first step in troubleshooting could be to check whether a query executes at all (I think it does). That would mean that the model as such is correct and no mapping problems are involved.

Having a KeyAttribute on a reference property is not common (and not necessary), but neither should it cause any problems. And I assume that you un-mapped both transient properties.

How can I troubleshoot the NullReferenceException?

The first thing to look at, obviously, is the stack trace. I've had limited success checking EF's source code where exceptions occurred. Sometimes it gives a clue.

Better is to compile EF's source code in debug mode and replace the current reference in your project by the compiled one. I've done that once and it put me on the right track. (Usually it's me doing something wrong).

like image 198
Gert Arnold Avatar answered Jun 30 '26 10:06

Gert Arnold



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!