0

I have an Epicor BPM in which I'm trying to test if an order (IE an entry in a temporary table ttOrderHed) has any lines in it (IE entries in a database table Db.OrderDtl).

When I test with an order that is known to have lines, this works; and when I use an order that doesn't, it returns a NullReferenceException:


var oh = (from o in ttOrderHed
          select o).FirstOrDefault();

var od = (from d in Db.OrderDtl
           where d.Company == oh.Company &&
                 d.OrderNum == oh.OrderNum
           select d).FirstOrDefault();

if ( od != null)
    {
      //do some Things and Stuff
    }

I thought maybe I was testing something null and therefore dropping out. I tried to get around it like this:

if (!(od == null)
     {
       //do stuff
     }

And got the same exception.

I have got debugging variables sprinkled throughout and I can say for sure that any attempt to do anything with var od makes me drop out of warp. For example, if I try to assign a value from it to a debugging variable that is already declared elsewhere b1 = od.OrderNum.ToString(); I get a NullReferenceException here too, just earlier.

I've spent the night researching this and have read this very good overview here:

What is a NullReferenceException, and how do I fix it?

and so far I'm drawing a blank. Part of the issue, I suppose, is I'm working inside Epicor's buil-in IDE which has a very limited syntax checker (it says I'm good to go) and an ersatz "Intellisense" tool, but otherwise provides no feedback or error messages. I can send output to the server's event viewer, of course, but all I get is the NullReferenceException itself.

Any feedback or suggestions would be appreciated. Many thanks in advance.

EDIT: in case it helps anyone, here's the code that worked in the end. I still have a lot to do but this one is solved.

    if (ttOrderHed.Any())
      {
      var oh = (from o in ttOrderHed select o).FirstOrDefault();

      if  ((from d in Db.OrderDtl where d.OrderNum == oh.OrderNum select d).Any())
           {
             var od = (from d in Db.OrderDtl
                        where   d.OrderNum == oh.OrderNum
                        select  d).FirstOrDefault();

             var tmp = od.OrderNum;

             // do stuff

           } // end if OrderDtl

      } // end if ttOrderHed
  • Can you place a check before `var od` to see if `oh` has value (`if(oh != null)`)? It seems to me that oh return null and then you try to access oh.OrderNum inside the linq query, and that is why you get the NullReferenceException. – theCuriousOne May 15 '20 at 15:21
  • Thanks @theCuriousOne yes, as I said I have debugging variables sprinkled throughout. In this case I send oh.OrderNum to the server's event viewer. oh is not returning null. – Steve Fossey May 15 '20 at 15:52

1 Answers1

0

It seems that you are new to linq and design patterns. It is usually a better idea to check if a collection is not empty before querying it. With that in mind, the following should work:

if (ttOrderHed == null || !ttOrderHed.Any()) { //Handle no value }

if (Db?.OrderDtl == null || !Db.OrderDtl.Any()) { //Handle no value }

var oh = ttOrderHed.First(); //Guaranteed to have a value

var ods = (
    from d in Db.OrderDtl
    where d.Company == oh.Company
        && d.OrderNum == oh.OrderNum
    select d).ToList();

if (!ods.Any()) { //Handle no value }

var od = ods[0];
Jeremy Morren
  • 346
  • 4
  • 13
  • Yes, I first heard the word "Linq" about a month ago, and wrote my first C# code around the same time. What's the question mark after the Db in the 2nd line? I will also have to check if the application allows access to the .Any() method - a lot of standard stuff is not allowed in the scope of a customization in Epicor. – Steve Fossey May 15 '20 at 15:59
  • The ? Is a null check on the DB variable. Any is a fairly common linq operator. – Jeremy Morren May 15 '20 at 16:19
  • OK, interesting. Db is the app's connection to the database scope outside of the customization. I'm still rebuilding using your answer, but I don't think Db or Db.OrderDtl will ever be null without a `where` clause. – Steve Fossey May 15 '20 at 16:24
  • So yes, the `.Any()` solution worked, checking for the existence of anything in a query before declaring the var. Quite surprising to me that I could put a query in an `if` statement – Steve Fossey May 15 '20 at 21:56