I have an issue inserting multiple entities to the Database when there is a reference to one of the entities from a DbQuery.
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.ArgumentNullException: Value cannot be null.
Parameter name: key
at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.FindIdentityMap(IKey key)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.GetDependents(InternalEntityEntry principalEntry, IForeignKey foreignKey)
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.InternalEntityEntryNotifier.PropertyChanged(InternalEntityEntry entry, IPropertyBase property, Boolean setModified)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetProperty(IPropertyBase propertyBase, Object value, Boolean setModified)
at Microsoft.EntityFrameworkCore.Update.ModificationCommand.PropagateResults(ValueBuffer valueBuffer)
at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeResultSetWithPropagationAsync(Int32 commandIndex, RelationalDataReader reader, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeAsync(RelationalDataReader reader, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeAsync(RelationalDataReader reader, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(DbContext _, ValueTuple`2 parameters, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IReadOnlyList`1 entriesToSave, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Program.Main(String[] args) in D:\Dev\Test\EFBug\EFBug\Program.cs:line 19
at Program.<Main>(String[] args)
```c#
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
internal class Program
{
private static async Task Main(string[] args)
{
using (var context = new MyContext())
{
await context.Database.EnsureCreatedAsync();
context.Bs.Add(new B
{
Value = "B Value",
A = new A { Value = "A Value" },
Cs = { new C { Value = "C Value" } }
});
await context.SaveChangesAsync();
}
Console.ReadLine();
}
}
public class MyContext : DbContext
{
public virtual DbSet As { get; set; }
public virtual DbSet Bs { get; set; }
public virtual DbSet
public virtual DbQuery
public MyContext() : base(new DbContextOptionsBuilder<MyContext>()
.UseSqlServer("Data Source=.;Initial Catalog=Test;Integrated Security=True")
.Options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Query<MyView>().ToView("MyView", "dbo");
}
}
public class A
{
public int Id { get; set; }
public string Value { get; set; }
public virtual ICollection Bs { get; set; } = new HashSet();
}
public class B
{
public int Id { get; set; }
public string Value { get; set; }
public int AId { get; set; }
public virtual A A { get; set; }
public virtual ICollection
}
public class C
{
public int Id { get; set; }
public string Value { get; set; }
public int BId { get; set; }
public virtual B B { get; set; }
}
public class MyView
{
public int BId { get; set; }
public virtual B B { get; set; }
}
```
EF Core version: 2.2.0
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: Windows 10 Pro
IDE: Visual Studio 2017 15.9.4
Regression introduced by https://github.com/aspnet/EntityFrameworkCore/pull/13468
There are few more places where we need to ignore FK on QueryType inside NavigationFixer.
Superseded by #14194 in 3.0
We just ran into this bug in one of our customer projects and are eagerly trying to figure out what exactly the problem is and how to work around it until this issue is closed. Unfortunately I can not really make sense of the linked Issues and PRs. Can someone be so kind and explain briefly how this is caused or why it is happening in 2.2 and not in 2.1? 馃槃
@michaelkargl I solved this by removing the navigation properties from the DbQuery class. The navigation property was used in a query, so I had to replace the navigation with a Join:
c#
// original:
var query = context.MyView.Where(...).Select(v => v.B);
// modified:
var query = context.MyView.Where(...).Join(context.Bs, v => v.BId, b => b.Id, (v, b) => b);
@michaelkargl I solved this by removing the navigation properties from the DbQuery class. The navigation property was used in a query, so I had to replace the navigation with a Join:
// original: var query = context.MyView.Where(...).Select(v => v.B); // modified: var query = context.MyView.Where(...).Join(context.Bs, v => v.BId, b => b.Id, (v, b) => b);
You sur, are a master. Someone put a view in the middle of our Context.
Marking the views' navigation-property as [NotMapped] worked for us.
public class DataImportRowData {
public long DataImportId { get; set; }
[NotMapped]
public DataImport DataImport { get; set; }
// ...
Same error here, removing navigation properties from the query type fixed the problem.
Any chance to get this fixed in 2.2.2?
In 2.1.* this was working properly
I also hit this. Thanks @Kloizdena for the workaround
Is there any form of workaround to this other than removing the navigation properties - it happens in my data migration loader where I am iterating a SQLReader to move data into my EF managed tables. I really don't want to drop navigation properties across the project!
@MCFHTAGENTS saving the entities in two turns also worked for me:
```c#
var b = new B
{
Value = "B Value",
A = new A { Value = "A Value" },
};
context.Bs.Add(b);
await context.SaveChangesAsync();
context.Cs.Add(new C { Value = "C Value", B = b });
await context.SaveChangesAsync();
instead of the original:
```c#
context.Bs.Add(new B
{
Value = "B Value",
A = new A { Value = "A Value" },
Cs = { new C { Value = "C Value" } }
});
await context.SaveChangesAsync();
Hmmm
I have the situation where I have three tiers of nested objects
```class A
{
[Key]
public int AId {get; set;}
public ICollection {get; set;}
}
public class B
{
[Key]
public int BId {get; set;}
[ForeignKey("AId")]
public A A {get; set;}
public int AId {get; set;}
public ICollection
}
public class C
{
public int CId {get; set;}
[ForeignKey("BId")]
public B B {get; set;}
public int BId {get; set;}}
I read in the data from another SQL source with a pattern like this:
List
while(reader.HasRead())
{
var X = X(){
};
newX.Add(X);
}
foreach(var Item in newX) {context.X.Add(Item)}
context.SaveChanges()
```
I find that when X is an A it works fine. In the B case the constructor includes a reference to A. I have tried both setting the
when X is a B it crashes out.
Hi there, I have just updated to 2.2.104 and am still seeing this:
System.ArgumentNullException: Value cannot be null.
Parameter name: key
at System.Collections.Generic.Dictionary2.FindEntry(TKey key)
at System.Collections.Generic.Dictionary2.TryGetValue(TKey key, TValue& value)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.FindIdentityMap(IKey key)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.GetDependents(InternalEntityEntry principalEntry, IForeignKey foreignKey)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.KeyPropertyChanged(InternalEntityEntry entry, IProperty property, IReadOnlyList1 containingPrincipalKeys, IReadOnlyList1 containingForeignKeys, Object oldValue, Object newValue)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.KeyPropertyChanged(InternalEntityEntry entry, IProperty property, IReadOnlyList1 keys, IReadOnlyList1 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.InternalEntityEntry.SetCurrentValue(IPropertyBase propertyBase, Object value)
at Microsoft.EntityFrameworkCore.Update.ColumnModification.set_Value(Object value)
at Microsoft.EntityFrameworkCore.Update.ModificationCommand.PropagateResults(ValueBuffer valueBuffer)
at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeResultSetWithPropagation(Int32 commandIndex, RelationalDataReader reader)
at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.Consume(RelationalDataReader reader)
--- End of inner exception stack trace ---
at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.Consume(RelationalDataReader reader)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(DbContext _, ValueTuple2 parameters)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteTState,TResult
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable1 commandBatches, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IReadOnlyList1 entries)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IReadOnlyList1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
@MCFHTAGENTS The fix is scheduled to be released as part of the EF Core/.NET Core 2.2.3 patch.
When is 2.2.3 expected?'
@Eirenarch It is expected to ship later this month.
Thanks all - looks like 2.2.3 has solved my problem 馃憤
Most helpful comment
@michaelkargl I solved this by removing the navigation properties from the DbQuery class. The navigation property was used in a query, so I had to replace the navigation with a Join:
c# // original: var query = context.MyView.Where(...).Select(v => v.B); // modified: var query = context.MyView.Where(...).Join(context.Bs, v => v.BId, b => b.Id, (v, b) => b);