Entity Framework CodeFirst KeyNotFoundException in MemberDomainMap

Trying to run an error in my eat datacontext implementation, which gives a rather cryptic error.

Test Name: Nodes_can_be_saved Test FullName: MyProj.Test.Integration.AFDataContextTest.Nodes_can_be_saved Test Source: c:\Users\pvencill. \Documents\Visual Studio 2012\Projects\MyProj\MyProj.Test\Integration\AFDataContextTest.cs : line 49 Test Outcome: Failed Test Duration: 0:00:01.4192808 Result Message: Test method MyProj.Test.Integration.AFDataContextTest.Nodes_can_be_saved threw exception: System.Data.Entity.Infrastructure.DbUpdateException: Error retrieving values from ObjectStateEntry. See inner exception for details. ---> System.Data.UpdateException: Error retrieving values from ObjectStateEntry. See inner exception for details. ---> System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary. Result StackTrace: at System.Collections.Generic.Dictionary`2.get_Item(TKey key) at System.Data.Mapping.ViewGeneration.Structures.MemberDomainMap.GetDomainInternal(MemberPath path) at System.Data.Mapping.ViewGeneration.QueryRewriting.FragmentQueryKB.CreateIsOfTypeCondition(MemberPath currentPath, IEnumerable`1 derivedTypes, MemberDomainMap domainMap) at System.Data.Mapping.ViewGeneration.QueryRewriting.FragmentQueryKB.CreateVariableConstraintsRecursion(EdmType edmType, MemberPath currentPath, MemberDomainMap domainMap, EdmItemCollection edmItemCollection) at System.Data.Mapping.ViewGeneration.QueryRewriting.FragmentQueryKB.CreateVariableConstraintsRecursion(EdmType edmType, MemberPath currentPath, MemberDomainMap domainMap, EdmItemCollection edmItemCollection) at System.Data.Mapping.ViewGeneration.ViewgenContext..ctor(ViewTarget viewTarget, EntitySetBase extent, IEnumerable`1 extentCells, CqlIdentifiers identifiers, ConfigViewGenerator config, MemberDomainMap queryDomainMap, MemberDomainMap updateDomainMap, StorageEntityContainerMapping entityContainerMapping) at System.Data.Mapping.ViewGeneration.ViewGenerator.CreateViewgenContext(EntitySetBase extent, ViewTarget viewTarget, CqlIdentifiers identifiers) at System.Data.Mapping.ViewGeneration.ViewGenerator.GenerateDirectionalViewsForExtent(ViewTarget viewTarget, EntitySetBase extent, CqlIdentifiers identifiers, KeyToListMap`2 views) at System.Data.Mapping.ViewGeneration.ViewGenerator.GenerateDirectionalViews(ViewTarget viewTarget, CqlIdentifiers identifiers, KeyToListMap`2 views) at System.Data.Mapping.ViewGeneration.ViewGenerator.GenerateAllBidirectionalViews(KeyToListMap`2 views, CqlIdentifiers identifiers) at System.Data.Mapping.ViewGeneration.ViewgenGatekeeper.GenerateViewsFromCells(List`1 cells, ConfigViewGenerator config, CqlIdentifiers identifiers, StorageEntityContainerMapping containerMapping) at System.Data.Mapping.ViewGeneration.ViewgenGatekeeper.GenerateViewsFromMapping(StorageEntityContainerMapping containerMapping, ConfigViewGenerator config) at System.Data.Mapping.StorageMappingItemCollection.ViewDictionary.SerializedGenerateViews(StorageEntityContainerMapping entityContainerMap, Dictionary`2 resultDictionary) at System.Data.Mapping.StorageMappingItemCollection.ViewDictionary.SerializedGetGeneratedViews(EntityContainer container) at System.Data.Common.Utils.Memoizer`2.<>c__DisplayClass2.<Evaluate>b__0() at System.Data.Common.Utils.Memoizer`2.Result.GetValue() at System.Data.Common.Utils.Memoizer`2.Evaluate(TArg arg) at System.Data.Mapping.StorageMappingItemCollection.ViewDictionary.GetGeneratedView(EntitySetBase extent, MetadataWorkspace workspace, StorageMappingItemCollection storageMappingItemCollection) at System.Data.Mapping.Update.Internal.ViewLoader.InitializeEntitySet(EntitySetBase entitySetBase, MetadataWorkspace workspace) at System.Data.Mapping.Update.Internal.ViewLoader.SyncInitializeEntitySet[TArg,TResult](EntitySetBase entitySetBase, MetadataWorkspace workspace, Func`2 evaluate, TArg arg) at System.Data.Mapping.Update.Internal.ViewLoader.SyncContains[T_Element](EntitySetBase entitySetBase, MetadataWorkspace workspace, Set`1 set, T_Element element) at System.Data.Mapping.Update.Internal.ExtractorMetadata..ctor(EntitySetBase entitySetBase, StructuralType type, UpdateTranslator translator) at System.Data.Mapping.Update.Internal.UpdateTranslator.GetExtractorMetadata(EntitySetBase entitySetBase, StructuralType type) at System.Data.Mapping.Update.Internal.ExtractorMetadata.ExtractResultFromRecord(IEntityStateEntry stateEntry, Boolean isModified, IExtendedDataRecord record, Boolean useCurrentValues, UpdateTranslator translator, ModifiedPropertiesBehavior modifiedPropertiesBehavior) at System.Data.Mapping.Update.Internal.RecordConverter.ConvertStateEntryToPropagatorResult(IEntityStateEntry stateEntry, Boolean useCurrentValues, ModifiedPropertiesBehavior modifiedPropertiesBehavior) --- End of inner exception stack trace --- at System.Data.Mapping.Update.Internal.RecordConverter.ConvertStateEntryToPropagatorResult(IEntityStateEntry stateEntry, Boolean useCurrentValues, ModifiedPropertiesBehavior modifiedPropertiesBehavior) at System.Data.Mapping.Update.Internal.ExtractedStateEntry..ctor(UpdateTranslator translator, IEntityStateEntry stateEntry) at System.Data.Mapping.Update.Internal.UpdateTranslator.LoadStateEntry(IEntityStateEntry stateEntry) at System.Data.Mapping.Update.Internal.UpdateTranslator.PullModifiedEntriesFromStateManager() at System.Data.Mapping.Update.Internal.UpdateTranslator.ProduceCommands() at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache) at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) at System.Data.Entity.Internal.InternalContext.SaveChanges() --- End of inner exception stack trace --- at System.Data.Entity.Internal.InternalContext.SaveChanges() at System.Data.Entity.Internal.LazyInternalContext.SaveChanges() at System.Data.Entity.DbContext.SaveChanges() at MyProj.Data.MyProjDataContext.SaveChanges() in c:\Users\pvencill. \Documents\Visual Studio 2012\Projects\MyProj\MyProj.Data\MyProjDataContext.cs:line 44 at MyProj.Test.Integration.AFDataContextTest.Nodes_can_be_saved() in c:\Users\pvencill. \Documents\Visual Studio 2012\Projects\MyProj\MyProj.Test\Integration\AFDataContextTest.cs:line 55 

Investigating the error led to several hits on Google, but the ones I found suggested that there was something to do with my exemplary relationships, although looking at the databases that generate the migration seems to me in my opinion. My respective models are:

My DBSets and modelCreating definition data context:

 public DbSet<Blip> Blips { get; set; } public DbSet<SensorAdapter> Sensors { get; set; } public DbSet<NodeReport> NodeReports { get; set; } public DbSet<Node> Nodes { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Blip>().Property(b => b.TimeStamp).HasColumnType("datetime2"); modelBuilder.Entity<Node>().HasMany<NodeReport>(n => n.NodeReports).WithRequired(nr=>nr.Node); modelBuilder.Entity<Blip>().HasMany<NodeReport>(b => b.NodeReports); base.OnModelCreating(modelBuilder); } 

The Blips and SensorAdapter objects worked just fine before adding NodeReports to them, so I suspect the project is there.

I have a basic Entity object that inherits all my stuff, which simply defines an Id property of type T; it works great.

NodeReport inherits from Report, the definition of which is here:

 public abstract class Report : Entity<long> { public Report() { Status = Status.Unknown; } public DateTime TimeStamp { get; set; } public Status Status { get; set; } public String Raw { get; set; } } 

NodeReport, in turn, is defined as follows:

 public class NodeReport : Report { public virtual Node Node { get; set; } //public virtual Blip Blip { get; set; } } 

I tried it both with Blip and without it, commented on it at the moment when I try to narrow the problem.

A Node is also a pretty rare class at a point in time:

 public class Node : Entity<long> { public Node () { NodeReports = new List<NodeReport>(); } public String HostName { get;set; } public String Description { get; set; } public virtual IList<NodeReport> NodeReports { get; set; } } 

Any suggestions would be highly appreciated, I beat myself trying to figure it out.

+2
source share
2 answers

Well, after a long search on my code and recovering from scratch, I found that the problem was that I had a Node derived class that had the Uri property as a property that did not explicitly display the map, since it does not have a default constructor (and maybe other reasons). I solved this for now by simply changing the property to String, which I check as Uri inside, although I would prefer a more elegant solution. I tried to map Uri and even my own subclass (w / default constructor) of Uri to type complextype, but that didn't help.

Nevertheless, he answers this question.

+3
source

With @Paul's answer, I could finally figure out my problem.

I use EF with Inheritance TPT (table for each type).

Source

To make it easier, I will use the same classes that are described in this tutorial.

 public abstract class BillingDetail { public int BillingDetailId { get; set; } public string Owner { get; set; } public string Number { get; set; } } [Table("BankAccounts")] public class BankAccount : BillingDetail { public string BankName { get; set; } public string Swift { get; set; } public Agency Agency { get; set; } /* I added it */ } public class InheritanceMappingContext : DbContext { public DbSet<BillingDetail> BillingDetails { get; set; } } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<BankAccount>().ToTable("BankAccounts"); modelBuilder.Entity<CreditCard>().ToTable("CreditCards"); } 

Problem

Please note that I have added a new Agency property inside BankAccount . Given that this is a complex type , if you don't match it, you will get this annoying error at runtime!

Decision

What I did just ignored this Agency property, but you can also map it to EF to know what to do. Both will stop the error.

The strangest thing is that not even matching a derived object (BankAccount) occurs. It seems that EF somehow knows that you created the derivation. So, if you try to run EF without matching some output, you will probably get this error too.

+1
source

Source: https://habr.com/ru/post/1237374/


All Articles