Reputation: 359
I have two tables with a relation between them.
Here are my models:
public class Locations
{
[Key]
public int LocationID { get; set; }
[Required(ErrorMessage = "This field is required!")]
[MaxLength(50, ErrorMessage = "The name is too long. Max. 50 characters allowed!")]
[Display(Name = "Location name:")]
public string Name { get; set; }
public int Position { get; set; }
public virtual LocationType LocationType { get; set; }
}
and
public class LocationType
{
[Key]
public int LocationTypeID { get; set; }
[Required(ErrorMessage = "This field is required!")]
[MaxLength(25, ErrorMessage = "The name is too long. Max. 25 characters allowed!")]
[Display(Name = "Location type:")]
public string Name { get; set; }
public int Position { get; set; }
public int HasChoicesOrInput { get; set; }
public virtual ICollection<Locations> Locations { get; set; }
}
In my configuration.cs file I have the following seed:
context.LocationType.AddOrUpdate(a => a.LocationTypeID,
new LocationType
{
Name = "AAAAA",
HasChoicesOrInput = 1,
Position = 1,
Locations = { new Locations { Name = "1111111", Position = 1 },
new Locations { Name = "2222222", Position = 2 }
}
});
Table definition:
CREATE TABLE [dbo].[Locations] (
[LocationID] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (50) NOT NULL,
[Position] INT NOT NULL,
[LocationType_LocationTypeID] INT NULL,
CONSTRAINT [PK_dbo.Locations] PRIMARY KEY CLUSTERED ([LocationID] ASC),
CONSTRAINT [FK_dbo.Locations_dbo.LocationTypes_LocationType_LocationTypeID] FOREIGN KEY ([LocationType_LocationTypeID]) REFERENCES [dbo].[LocationTypes] ([LocationTypeID])
);
CREATE TABLE [dbo].[LocationTypes] (
[LocationTypeID] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (25) NOT NULL,
[Position] INT NOT NULL,
[HasChoicesOrInput] INT NOT NULL,
CONSTRAINT [PK_dbo.LocationTypes] PRIMARY KEY CLUSTERED ([LocationTypeID] ASC)
);
When I do an Update-Database, I get an "Object reference not set to an instance of an object." error.
Why? The tables exist in the database, the relation too. What am I missing here?
Upvotes: 1
Views: 61
Reputation: 14896
The Locations
intializer
new LocationType
{
Name = "AAAAA",
HasChoicesOrInput = 1,
Position = 1,
Locations = { new Locations { Name = "1111111", Position = 1 },
new Locations { Name = "2222222", Position = 2 }
}
});
does not create a Locations
collection. It calls the property getter to get the existing Locations
collection and calls Add
on it. Since you never assigned anything to that property, you get the NullReferenceException
.
This syntax is described in C# language specification, section 7.6.10.2 Object initializers:
A member initializer that specifies a collection initializer after the equals sign is an initialization of an embedded collection. Instead of assigning a new collection to the field or property, the elements given in the initializer are added to the collection referenced by the field or property. You should create a new instance of a collection (for example a list or an array) and assign it to
Locations
property in the initializer:
new LocationType
{
Name = "AAAAA",
HasChoicesOrInput = 1,
Position = 1,
Locations = new List<Locations>
{
new Locations { Name = "1111111", Position = 1 },
new Locations { Name = "2222222", Position = 2 }
}
});
Upvotes: 3