EF4.1 — Атрибут, равный нулю во время выполнения

#c# #entity-framework #entity-framework-4 #entity-framework-4.1

#c# #entity-framework #entity-framework-4 #entity-framework-4.1

Вопрос:

Сначала я использую код EF4.1 для создания простого приложения базы данных с серверной частью SQL CE 4. У меня есть класс Product и класс CallItem, определенные как 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; }
    }
  

редактировать — Когда я создаю коллекцию элементов вызова с помощью запроса LINQ, я не могу получить доступ к атрибутам продукта, прикрепленным к каждому элементу вызова, например

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

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

Запрос базы данных показывает, что заполняется Productid в CallItems. Однако следующая строка генерирует исключение NullReferenceException во время выполнения:

 nrs.prodCode = callitem.Product.Code;
  

Потому что callitem .Продукт оценивается как нулевой. Связано ли это с отложенной загрузкой, и если да, то как я могу решить проблему?

RunSheet — это другой класс, nrs — это экземпляр, атрибут ‘ProdCode’ которого я хочу заполнить кодом продукта CallItem.

Спасибо!

Комментарии:

1. вы уверены, что это сложный тип?

2. Я думал, что все, что не было примитивным типом (char, int, float и т. Д.), Было сложными типами.

3. это должно дать вам лучшее представление о EF weblogs.asp.net/manavi/archive/2011/03/28 /…

4. хорошо, спасибо — я изменю заголовок и немного почитаю!

5. RunSheet — это еще один объект, атрибут ProdCode которого я хочу установить в код продукта.

Ответ №1:

Из этого кода то, что вы показали, должно работать. Вы пробовали явную загрузку?

 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;
}
  

Комментарии:

1. блестяще, это решило проблему. спасибо nemesv! (Я проголосую, когда у меня будет больше репутации — это был мой первый вопрос).

Ответ №2:

 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);
            }
  

Я написал приведенный выше код со следующим выводом

 CallItemId 1
ProductId 1
  

Профилировщик sql показал это

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

Это было слишком долго для комментария, поэтому я поместил его здесь .

Комментарии:

1. Спасибо. Я перефразировал вопрос, чтобы сделать вещи немного понятнее.