Tony Vitabile
Tony Vitabile

Reputation: 8594

Many to many navigation property is null

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?

Upvotes: 2

Views: 82

Answers (2)

user1666620
user1666620

Reputation: 4808

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

Upvotes: 1

ocuenca
ocuenca

Reputation: 39326

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>();
   }
   //...
}

Upvotes: 1

Related Questions