2

I am working on Web Api where I would have to create Data Transfer Objects for displaying data on the UI of application.

I am working with Code First approach here is my Domain class

   public class Employee
    {

        [Key]
        public int BusinessEntityId { get; set; }


        [Required]
        [MaxLength(50)]

        public string JobTitle { get; set; }

        [Required]
        [DataType(DataType.DateTime)]
        public DateTime BirthDate { get; set; }


        [Required]
        [MaxLength(1)]
        public string MaritalStatus { get; set; }

        [Required]
        [MaxLength(1)]
        public string Gender { get; set; }

        [Required]
        [DataType(DataType.DateTime)]
        public DateTime HireDate { get; set; }

        [Required]
        public Boolean SalariedFlag { get; set; }

        public ICollection<EmployeePayHistory> PayHistories { get; set; }

    }

Here is my Data Transfer Object(DTO) Class

 public class EmployeePayHistoryListDTO
    {

        public int Id { get; set; }

        public DateTime RateChangeDate { get; set; }

        public Decimal Rate { get; set; }

        public Int16 PayFrequency { get; set; }

        public String JobTitle { get; set; }

        public String Gendre { get; set; }

    }

Now As PayHistories is collection in my Domain class I what i am doing is i am creating a new class of which has collection of my DTO class type EmployeePayHistoryListDTO

 public class EmployeeRelatedCollections
    {
        public ICollection<EmployeePayHistoryListDTO> PayHistories { get; set; }
    }

So from my repository I am getting data correctly via following EF statement

 _context.Employees.Include("PayHistories")
                                     .Include("PayHistories")                                 
                                     .Single(e=>e.BusinessEntityId==id);

But where i am converting collection of my Employee class(Domain Class) to collection of my DTO type there i am getting error here is the code

PayHistories = (from ph in employee.PayHistories
                            select new EmployeePayHistoryListDTO
                            {
                                Id = ph.BusinessEntityId,
                                RateChangeDate = ph.RateChangeDate,
                                Rate = ph.Rate,
                                PayFrequency = ph.PayFrequency,
                                JobTitle = ph.Employee.JobTitle,
                                Gendre = ph.Employee.Gender
                            }).ToList();


          I am getting following exception below is summary 

Execption getting

 System.NullReferenceException ,  
Additional Information: Object reference Not set to an instance of an object.

 Troubleshooting tips
 1.  Check to determine if the object is null before calling the method,
 2.  Use new keyword to create an object instance.
tschmit007
  • 7,559
  • 2
  • 35
  • 43
Husrat Mehmood
  • 2,270
  • 1
  • 20
  • 22

4 Answers4

3

Looks like you failed to initialize your employee object. When the null reference exception occurs you should be able to check the value of the employee object by hovering your mouse on it and see that it is null. The nullreference exception occurs when you try to access a field on your null object (in this case, PayHistories).

See if this code avoids the exception:

if(employee!=null){
    if(employee.PayHistories.Any()){

        PayHistories = (from ph in employee.PayHistories
                        select new EmployeePayHistoryListDTO
                        {
                            Id = ph.BusinessEntityId,
                            RateChangeDate = ph.RateChangeDate,
                            Rate = ph.Rate,
                            PayFrequency = ph.PayFrequency,
                            JobTitle = ph.Employee.JobTitle,
                            Gendre = ph.Employee.Gender
                        }).ToList();
    }
}
C Bauer
  • 5,003
  • 4
  • 33
  • 62
1

From:

PayHistories = (from ph in employee.PayHistories
                        select new EmployeePayHistoryListDTO
                        {
                            Id = ph.BusinessEntityId,
                            RateChangeDate = ph.RateChangeDate,
                            Rate = ph.Rate,
                            PayFrequency = ph.PayFrequency,
                            JobTitle = ph.Employee.JobTitle,
                            Gendre = ph.Employee.Gender
                        }).ToList();

Can you make it:

PayHistories = (from ph in employee.PayHistories
                        select new EmployeePayHistoryListDTO
                        {
                            Id = ph.BusinessEntityId,
                            RateChangeDate = ph.RateChangeDate,
                            Rate = ph.Rate,
                            PayFrequency = ph.PayFrequency

                        }).ToList();

and see if the exception still occurs?

It looks like based on that query you would have:

Employee -> PaymentHistory -> Employee.

In your statement:

_context.Employees.Include("PayHistories")
                                 .Include("PayHistories")                                 
                                 .Single(e=>e.BusinessEntityId==id);

It doesn't look like you would include the additional employee object on top of your PayHistories (and did you intentially include it twice?). I believe you could also use a linq statement to get more strongly typed includes like

.Include(i => i.PayHistories)

Hopefully this will help you!

Kritner
  • 13,557
  • 10
  • 46
  • 72
  • If I do the way you suggested .Include(i => i.PayHistories) i get following " cann't convert lamda expression of type string because it is not a delegate type" – Husrat Mehmood Sep 03 '14 at 14:14
  • 1
    Apparently the Include is an extension method, you need to "using System.Data.Entity" to use it. PITA I know, I always forget the namespace it's from, and you can't right click resolve. http://stackoverflow.com/questions/4544756/using-include-in-entity-framework-4-with-lambda-expressions – Kritner Sep 03 '14 at 14:27
  • Here you are correct 100% thank you very much.but issue is still there @Kritner. – Husrat Mehmood Sep 03 '14 at 14:37
0

Make sure that employee.PayHistories does not contain null entries, or check it inside the query:

PayHistories = (from ph in employee.PayHistories where null != ph
etc. . .

Also, you're referring to a possibly lazy-loaded / uninitialized property on "ph" (Employee), which may also be null.

t0yk4t
  • 854
  • 8
  • 10
  • If employee is null this will still throw an exception. – C Bauer Sep 03 '14 at 14:06
  • That's correct - I'd convert the strange SLQy linq code to extension method calls to get a little more flexibility in error checking. – t0yk4t Sep 03 '14 at 14:07
0

Here is how i solved my problem.I was having multiple references those were not loading properly.

There were two approaches

Approach 1.

The Include extension method overload which takes an Expression<Func<T,U>>

_context.Employees.Include("PayHistories.furtherreferencename").Include("PayHistories.furtherReference");

Approach 2.

Use Strongly typed Include method.

_context.Employees.Include(i=>i.PayHistories.select(e=>e.FurtherReference)).Include(i=>i.PayHistories.select(e=>e.FurtherReference));

Husrat Mehmood
  • 2,270
  • 1
  • 20
  • 22