1

I'm writing two LINQ queries where I use my first query's result set in my second query.

But in some cases when there is no data in the database table my first query returns null, and because of this my second query fails since wsdetails.location and wsdetails.worklocation are null causing an exception.

Exception:

Object reference not set to an instance of an object

My code is this:

        var wsdetails = (from assetTable in Repository.Asset
                         join userAsset in Repository.UserAsset on
                         assetTable.Asset_Id equals userAsset.Asset_Id
                         join subLocationTable in Repository.SubLocation on
                         assetTable.Sub_Location_Id equals subLocationTable.Sub_Location_ID
                         where userAsset.User_Id == userCode
                         && assetTable.Asset_TypeId == 1 && assetTable.Asset_SubType_Id == 1
                         select new { workstation = subLocationTable.Sub_Location_Name, location = assetTable.Location_Id }).FirstOrDefault();


            result = (from emp in this.Repository.Employee
                      join designation in this.Repository.Designation on
                      emp.DesignationId equals designation.Id
                      where emp.Code == userCode
                      select new EmployeeDetails
                      {                             
                          firstname = emp.FirstName,
                          lastname = emp.LastName,                              
                          designation = designation.Title,
                          LocationId = wsdetails.location,
                          WorkStationName = wsdetails.workstation
                      }).SingleOrDefault();

As a workaround I can check

if wsdetails == null

and change my second LINQ logic, but I believe there are some ways to handle null values in LINQ itself like the ?? operator.

But I tried this and it didn't work for me.

Any help?

3 Answers 3

3

The problem is EF can't translate the null-coalescing operator to SQL. Personally I don't see what's wrong with checking the result with an if statement before executing the next query. However, if you don't want to do that, then because your result is always going to be a single query why not do something like:

var wsdetails = (from assetTable in Repository.Asset 
                 join userAsset in Repository.UserAsset on 
                 assetTable.Asset_Id equals userAsset.Asset_Id 
                 join subLocationTable in Repository.SubLocation on 
                 assetTable.Sub_Location_Id equals subLocationTable.Sub_Location_ID 
                 where userAsset.User_Id == userCode 
                 && assetTable.Asset_TypeId == 1 && assetTable.Asset_SubType_Id == 1 
                 select new { workstation = subLocationTable.Sub_Location_Name, location = assetTable.Location_Id }).FirstOrDefault();  

result = (from emp in this.Repository.Employee 
          join designation in this.Repository.Designation on 
          emp.DesignationId equals designation.Id 
          where emp.Code == userCode 
          select new EmployeeDetails 
          {                              
              firstname = emp.FirstName, 
              lastname = emp.LastName,                               
              designation = designation.Title
           }).SingleOrDefault();

result.LocationId = wsdetails != null ? wsdetails.location : "someDefaultValue";
result.WorkStationName = wsdetails != null ? wsdetails.workstation ?? "someDefaultValue"; 
Sign up to request clarification or add additional context in comments.

2 Comments

But if it's wsdetails that's null, then wsdetails.location ?? "someDefaultValue" will still explode. What we need here is not the ?? operator but the (until now non-existing) operator .? which "dots" cautiously (checking for null before member access).
@JeppeStigNielsen oops that was a typo thanks, I did mean to use the standard ternary operator there. .? is not a valid C# operator. If you read the link you posted it was "contemplated" it was never implemented :)
2

Instead of the "binary" operator ?? maybe you should use the good old ternary one, ? :, like in

wsdetails != null ? wsdetails.location : null

2 Comments

?? is called the null-coalescing operator
1

Try not evaluating the first query, and use it in the second query. This should result in a single SQL statement.

var wsdetails = (from assetTable in Repository.Asset
                         join userAsset in Repository.UserAsset on
                         assetTable.Asset_Id equals userAsset.Asset_Id
                         join subLocationTable in Repository.SubLocation on
                         assetTable.Sub_Location_Id equals subLocationTable.Sub_Location_ID
                         where userAsset.User_Id == userCode
                         && assetTable.Asset_TypeId == 1 && assetTable.Asset_SubType_Id == 1
                         select new { workstation = subLocationTable.Sub_Location_Name, location = assetTable.Location_Id });
// wsdetails is still an IEnumerable/IQueryable


        result = (from emp in this.Repository.Employee
                  join designation in this.Repository.Designation on
                  emp.DesignationId equals designation.Id
                  where emp.Code == userCode
                  select new EmployeeDetails
                  {                             
                      firstname = emp.FirstName,
                      lastname = emp.LastName,                              
                      designation = designation.Title,
                      LocationId = wsdetails.First().location,
                      WorkStationName = wsdetails.First().workstation
                  }).SingleOrDefault();

9 Comments

You are still going to get the same problem as wsdetails can still be null so wsdetails.First().location will throw an exception.
Since wsdetails is an IQueryable it should be translated to SQL.
No, the executed .First() is not IEnumerable.First() but IQueryable.First() so it should be translated to SQL, and be executed on the database in SQL. Which will be a JOIN with a SELECT TOP 1 or something.
Then SQL will return a NULL value as the value for LocationId and WorkStationName (the properties in the anonymous type in the second linq query).
Okay, yep, if it is another database, then EF cannot do it in one query. So my solution is not applicable in this case. One of the other answers should suffice.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.