-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
Steps to reproduce
Use the following code to reproduce:
class Program
{
static void Main(string[] args)
{
if (File.Exists("test.db"))
File.Delete("test.db");
using (var context = new WidgetContext())
{
context.Database.Migrate();
}
using (var context = new WidgetContext())
{
for (int i = 0; i < 10; i++)
{
var w = new Widget();
context.Widgets.Add(w);
}
context.SaveChanges();
}
using (var context = new WidgetContext())
{
var widgets = context.Widgets.ToList();
widgets[0].ParentWidget = widgets[1];
context.SaveChanges();
}
using (var context = new WidgetContext())
{
var widgets = context.Widgets.ToList();
try
{
Console.WriteLine(widgets[1].ChildWidgets.Count);
}
catch (Exception e)
{
Console.WriteLine("oops, didn't connect childwidgets collection.");
Console.WriteLine(e);
}
widgets[0].ParentWidget = widgets[2];
try
{
context.SaveChanges();
Console.WriteLine("Saved change of parent.");
}
catch (Exception e)
{
Console.WriteLine("oops, couldn't alter the parent Id");
Console.WriteLine(e);
}
}
}
}
class WidgetContext : DbContext
{
public DbSet<Widget> Widgets { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Filename=test.db");
}
}
public class Widget
{
public int Id { get; set; }
public int? ParentWidgetId { get; set; }
[InverseProperty(nameof(ChildWidgets))]
[ForeignKey(nameof(ParentWidgetId))]
public Widget ParentWidget { get; set; }
[InverseProperty(nameof(ParentWidget))]
public List<Widget> ChildWidgets { get; set; }
}
Add nuget packages for appropriate version of EntityFramework.Sqlite/EntityFrameworkCore.Sqlite and EntityFramework.Commands/EntityFrameworkCore.Tools.
Create an initial migration.
The issue
On RC2, the ChildWidgets collection on each Widget when loading the entire table, so the line
Console.WriteLine(widgets[1].ChildWidgets.Count);
throws a NullReferenceException. This works correctly on RC1.
Additionally, changing the ParentWidget of a Widget that already has a parent set fails when the changes are saved to the database with the following exception.
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.RemoveFromCollectionSnapshot(IPropertyBase propertyBase, Object removedEntity)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.RemoveFromCollection(InternalEntityEntry entry, INavigation navigation, IClrCollectionAccessor collectionAccessor, Object value)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.KeyPropertyChanged(InternalEntityEntry entry, IProperty property, IReadOnlyList`1 containingPrincipalKeys, IReadOnlyList`1 containingForeignKeys, Object oldValue, Object newValue)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.KeyPropertyChanged(InternalEntityEntry entry, IProperty property, IReadOnlyList`1 keys, IReadOnlyList`1 foreignKeys, Object oldValue, Object newValue)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectKeyChange(InternalEntityEntry entry, IProperty property)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.PropertyChanged(InternalEntityEntry entry, IPropertyBase propertyBase, Boolean setModified)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.PropertyChanged(InternalEntityEntry entry, IPropertyBase property, Boolean setModified)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetProperty(IPropertyBase propertyBase, Object value, Boolean setModified)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.SetForeignKeyProperties(InternalEntityEntry dependentEntry, InternalEntityEntry principalEntry, IForeignKey foreignKey, Boolean setModified)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.NavigationReferenceChanged(InternalEntityEntry entry, INavigation navigation, Object oldValue, Object newValue)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.NavigationReferenceChanged(InternalEntityEntry entry, INavigation navigation, Object oldValue, Object newValue)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectNavigationChange(InternalEntityEntry entry, INavigation navigation)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectNavigationChanges(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectRelationshipChanges(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectChanges(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectChanges(IStateManager stateManager)
at Microsoft.EntityFrameworkCore.DbContext.TryDetectChanges(IStateManager stateManager)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
Again, this works correctly on RC1. I suspect this may be a consequence of the ChildWidget list being left null - so a maybe just another symptom of the first problem.
Further technical details
EF Core version: 1.0.0-rc2-final
Operating system: Windows 10 Pro x64
Visual Studio version: VS2015 update 2
Other details about my project setup: Console App, Target : .NET 4.5.2