2

I have these two classes in my EF 6 code-first model:

public class Category {

    public int CategoryId { get; set; }

    [Required, MaxLength( 128 ), Index( IsUnique = true)]
    public string CategoryName { get; set; }

    public string Description { get; set; }

    public virtual ICollection<Article> Articles { get; set; }
}

public class Article {

    [DatabaseGenerated( DatabaseGeneratedOption.Identity ), Key]
    public int ArticleId { get; set; }

    [Required, MaxLength( 128 ), Index( IsUnique = true )]
    public string ArticleName { get; set; }

    public virtual ICollection<Category> Categories { get; set; }

    public string Description { get; set; }

}

I have this code in my data access layer to create a new article:

public Article AddArticle( string articleName, int[] categoryIds ) {
    if ( string.IsNullOrWhiteSpace( articleName ) )
        throw new ArgumentNullException( nameof( articleName ), Properties.Resources.ArticleNameWasNull );
    if ( categoryIds == null )
        throw new ArgumentNullException(nameof(categoryIds), Properties.Resources.CategoryIdsAreNull );

    using ( var context = new ArticleContext() ) {
        var article = new Article {
            ArticleName = articleName
        };
        foreach ( var category in context.Categories.Where( c => categoryIds.Contains( c.CategoryId ) ) )
            article.Categories.Add( category );
        context.Articles.Add( article );
        context.SaveChanges();
        return article;
    }
}

When I call this method, I get a NullReferenceException on the line in the foreach loop that adds the Category object to the article.Categories collection.

Obviously the Categories collection isn't initialized in the call to new Article(). What am I missing?

Tony Vitabile
  • 8,298
  • 15
  • 67
  • 123
  • Possible duplicate of [Add to an ICollection](http://stackoverflow.com/questions/7808744/add-to-an-icollection) – user1666620 Apr 20 '16 at 14:39

2 Answers2

1

You can't add an item to a null collection. You need to initialize article.Categories as a new collection.

article.Categories = new List<Category>();

foreach ( var category in context.Categories.Where( c => categoryIds.Contains( c.CategoryId ) ) )
    article.Categories.Add( category );

Alternatively add it where you are creating the object:

var article = new Article {
    ArticleName = articleName,
    Categories = new List<Category>()
};
user1666620
  • 4,800
  • 18
  • 27
  • Thank you for your response. I realize that I need to instantiate the collection. I just didn't know what type of object to instantiate, since `ICollection` is an interface, not a class, and can't be instantiated. – Tony Vitabile Apr 20 '16 at 14:37
  • @TonyVitabile you can use `List` http://stackoverflow.com/questions/7808744/add-to-an-icollection – user1666620 Apr 20 '16 at 14:39
1

To avoid that kind of exception I always initialize the collection properties in a empty constructor:

public class Article 
{
   public Article()
   {
      Categories =new List<Category>();
   }
   //...
}
ocuenca
  • 38,548
  • 11
  • 89
  • 102