2016-03-18 2 views
3

Когда я комментирую dishes.Add(new Dishes { DishID = 8, DishName = "Name", DishTypeID = 2, IngredientID = 2 });, я получаю в ll один элемент Amount="1 cup" DishID=1 Ingridient="egg" Name ="Soup". При раскомментировании этой ошибки при создании строки исключение нулевой ссылки в b.IngredientTypeID. Главный вопрос, как получить в ll два элемента, в:Ошибка null reference в левом соединении

1) Amount="1 cup" DishID=1 Ingridient="egg" Name ="Soup"

2) Amount=null DishID=2 Ingridient=null Name =null

namespace ConsoleApplication1 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 
     List<Dishes> dishes = new List<Dishes>(); 
     List<Ingredients> ingredients = new List<Ingredients>(); 
     List<Amount> amount = new List<Amount>(); 
     List<Ingredient> ingredient = new List<Ingredient>(); 

     dishes.Add(new Dishes { DishID = 1, DishName = "Soup", DishTypeID = 1, IngredientID = 1 }); 
     //dishes.Add(new Dishes { DishID = 8, DishName = "Name", DishTypeID = 2, IngredientID = 2 }); 
     ingredients.Add(new Ingredients { AmountID = 2, IngredientID = 1, IngredientTypeID = 1, IngredientUniqID = 1 }); 
     amount.Add(new Amount { AmountID = 2, AmountName = "1 cup" }); 
     ingredient.Add(new Ingredient { IngredientID = 1, IngredientName = "egg" }); 

     var test = from dish in dishes 
        join ing in ingredients on dish.IngredientID equals ing.IngredientID into result 
        from b in result.DefaultIfEmpty() 
        join i in ingredient on b.IngredientTypeID equals i.IngredientID into r 
        from c in r.DefaultIfEmpty() 
        join am in amount on b.AmountID equals am.AmountID into s 
        from t in s.DefaultIfEmpty() 
        select new DisplayRecipe { Name = dish.DishName, Amount = t.AmountName, Ingredient = c.IngredientName, DishID = dish.DishID }; 

     List<DisplayRecipe> ll = test.ToList(); 
    } 
} 
public partial class Dishes 
{ 
    public int DishID { get; set; } 
    public string DishName { get; set; } 
    public Nullable<int> DishTypeID { get; set; } 
    public Nullable<int> IngredientID { get; set; } 
} 

public partial class Ingredients 
{ 
    public int IngredientID { get; set; } 
    public Nullable<int> AmountID { get; set; } 
    public Nullable<int> IngredientTypeID { get; set; } 
    public int IngredientUniqID { get; set; } 
} 

public partial class Amount 
{ 
    public int AmountID { get; set; } 
    public string AmountName { get; set; } 
} 
public partial class Ingredient 
{ 
    public int IngredientID { get; set; } 
    public string IngredientName { get; set; } 
} 
public class DisplayRecipe 
{ 
    public string Name { get; set; } 
    public string Ingredient { get; set; } 
    public string Amount { get; set; } 
    public int DishID { get; set; } 
} 
} 
+0

ингридиенты и ingridient два различных списка. Это проблема с плохим наименованием. – A191919

ответ

3

Проблема заключается в том, что любой из b, c, t переменных может быть null из-за DefaultIfEmpty и вы должны учитывать, что в любом доступе членов, в том числе присоединиться условия.

Если вы используете C# 6 (VS2015), вы можете использовать оператор ?. как этот

var test = from dish in dishes 
      join ing in ingredients on dish.IngredientID equals ing.IngredientID into result 
      from b in result.DefaultIfEmpty() 
      join i in ingredient on b?.IngredientTypeID equals i.IngredientID into r 
      from c in r.DefaultIfEmpty() 
      join am in amount on b?.AmountID equals am.AmountID into s 
      from t in s.DefaultIfEmpty() 
      select new DisplayRecipe { Name = dish.DishName, Amount = t?.AmountName, Ingredient = c?.IngredientName, DishID = dish.DishID }; 

время в предварительно C# 6:

var test = from dish in dishes 
      join ing in ingredients on dish.IngredientID equals ing.IngredientID into result 
      from b in result.DefaultIfEmpty() 
      join i in ingredient on b != null ? b.IngredientTypeID : null equals i.IngredientID into r 
      from c in r.DefaultIfEmpty() 
      join am in amount on b != null ? b.AmountID : null equals am.AmountID into s 
      from t in s.DefaultIfEmpty() 
      select new DisplayRecipe { Name = dish.DishName, Amount = t != null ? t.AmountName : null, Ingredient = c != null ? c.IngredientName : null, DishID = dish.DishID }; 
1

Проблема вы добавили эту строку:

dishes.Add(new Dishes { DishID = 8, DishName = "Name", DishTypeID = 2, IngredientID = 2 }); 

Но не также добавьте другие линии, которые зависят от вашего соединения (пример):

ingredients.Add(new Ingredients { AmountID = 2, IngredientID = 2, IngredientTypeID = 1, IngredientUniqID = 1 }); 
ingredient.Add(new Ingredient { IngredientID = 2, IngredientName = "ham" }); 

Итак, когда ваша программа пытается найти идентификатор компонента из 2, потому что он добавлен в блюда, он не находит его и создает ошибку.

Пример кода, который работает:

 dishes.Add(new Dishes { DishID = 1, DishName = "Soup", DishTypeID = 1, IngredientID = 1 }); 
    dishes.Add(new Dishes { DishID = 8, DishName = "Name", DishTypeID = 2, IngredientID = 2 }); 
    ingredients.Add(new Ingredients { AmountID = 2, IngredientID = 1, IngredientTypeID = 1, IngredientUniqID = 1 }); 
    ingredients.Add(new Ingredients { AmountID = 2, IngredientID = 2, IngredientTypeID = 1, IngredientUniqID = 1 }); 
    amount.Add(new Amount { AmountID = 2, AmountName = "1 cup" }); 
    ingredient.Add(new Ingredient { IngredientID = 1, IngredientName = "egg" }); 
    ingredient.Add(new Ingredient { IngredientID = 2, IngredientName = "ham" }); 
Смежные вопросы