dav83
dav83

Reputation: 322

EF4.1 - Attribute Evaluating to null at runtime

I'm using EF4.1 code first to create a simple database app with SQL CE 4 backend. I have a Product class and a CallItem class defined as so:

    class CallItem
    {
        public int id { get; set; }
        public float discount { get; set; } 
        public virtual Product Product { get; set; }
    }

    class Product
    {
        public int id { get; set; }

        public decimal BaseCost { get; set; }
        public int UnitSize { get; set; }
        public bool isWasteOil { get; set; }

        public string Code { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string Ingredients { get; set; }
    }

edit - When I am creating a collection of CallItems using a LINQ query, I cannot access the attributes of the Product attached to each CallItem, eg

var callItems = from ci in context.CallItems select ci;

foreach(CallItem callItem in callItems)
{
    RunSheet nrs = new RunSheet();
    nrs.prodCode = callitem.Product.Code;
}

Interrogating the database shows that Productid in CallItems is being populated. However, the following line generates a NullReferenceException during run time:

nrs.prodCode = callitem.Product.Code;

Because callitem.Product is evaluating to null. Is this something to do with lazy loading and if so how can I resolve the issue?

RunSheet is another class, nrs is an instance whose attribute 'prodCode' I want to populate with the CallItem's Product's code.

Thanks!

Upvotes: 2

Views: 136

Answers (2)

nemesv
nemesv

Reputation: 139778

From that code what you've showed it should work. Have you tried explicit loading?

var callItems = from ci in context.CallItems.Include(c => c.Product) select ci;

foreach(CallItem callItem in callItems)
{
    RunSheet nrs = new RunSheet();
    nrs.prodCode = callitem.Product.Code;
}

Upvotes: 2

ashutosh raina
ashutosh raina

Reputation: 9314

public class CallItem
    {
        public int Id { get; set; }
        public float Discount { get; set; }
        public virtual Product Product { get; set; }
    }
 public class Product
    {
        public int Id { get; set; }

        public decimal BaseCost { get; set; }
        public int UnitSize { get; set; }
        public bool IsWasteOil { get; set; }

        public string Code { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string Ingredients { get; set; }
    }
using (var context = new StackOverFlowContext())
            {
                var p = new Product
                                {
                                    Id = 1,
                                    BaseCost = 200,
                                    Code = "Hola",
                                    Description = "Soe description",
                                    Ingredients = "Some  ingredients",
                                    IsWasteOil = true,
                                     Name = "My Product",
                                     UnitSize = 10

                                };

                var item = new CallItem
                                    {
                                        Id = 101,
                                        Discount = 10,
                                         Product = p
                                    };
                context.CallItems.Add(item);
                context.SaveChanges();
                var result = from temp in context.CallItems
                             select temp;
                Console.WriteLine("CallItem Id"+result.First().Id);
                Console.WriteLine("ProductId"+result.First().Product.Id);
            }

I wrote the above code with the following output

CallItemId 1
ProductId 1

The sql Profiler showed this

SELECT TOP (1) 
[c].[Id] AS [Id], 
[c].[Discount] AS [Discount], 
[c].[Product_Id] AS [Product_Id]
FROM [dbo].[CallItems] AS [c]

It was too long for a comment ,so i put it here .

Upvotes: 0

Related Questions