2012-11-29 54 views
2

试图往下跑在我的EF的DataContext执行错误时产生一个相当神秘的错误。实体框架CodeFirst KeyNotFoundException在MemberDomainMap

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 

研究导致了对谷歌几命中的错误,但我发现那些认为它的东西做瓦特/我的模型关系,虽然在看着那产生的迁移数据库,一切似乎都在以我的眼睛。我的相关型号如下:

我的数据上下文DBSets和modelCreating定义:

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

的光点和SensorAdapter对象细加NodeReports他们之前的工作,所以我怀疑它在那里,该项目位于。

我有我所有的东西从,这仅仅定义类型T的标识财产继承的基础实体对象;这工作正常。反过来

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被这样定义:

NodeReport从报表,它的定义是在这里继承

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

我既没有在那里的光点试了一下,注释掉在当我尝试缩小问题的范围时

节点在这段时间也是一个相当稀疏的类:

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

任何建议,将不胜感激,我已经打自己了试图找到答案。

回答

3

好了,经过多次通过我的代码搜索和从头开始重建,我发现这个问题实际上我有一个派生类节点,它有一个URI作为一个属性,它显然没有映射,因为它不具备默认构造函数(可能还有其他原因)。我现在通过简单地将属性更改为字符串来解决这个问题,我在内部验证它为Uri,但我宁愿选择更优雅的解决方案。我试图将Uri和Uri的自定义子类(w /默认构造函数)映射到复杂类型,但这并没有帮助。

尽管如此,这个问题上面回答。

+1

谢谢!你救了我几个小时! – gisek

+0

你也节省了我的时间!非常感谢你 ! – eka808

1

随着@保罗的答案,我终于可以找出我的问题。

我正在使用EF与继承TPT(表每种类型)。

的源代码

为了方便,我将使用在this教程discribed相同的类。

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

问题

请注意,我添加了一个名为AgencyBankAccount内新属性。鉴于它是一个复杂类型,如果你不映射它,你会在运行时得到这个恼人的错误!

解决方案

我所做的只是忽略此属性Agency,但你也可以把它映射到EF知道该怎么办。两者都会阻止错误。

最奇怪的是即使没有映射派生实体(BankAccount)也会出现问题。 EF似乎知道你创建了派生。因此,如果您试图在未映射某些派生的情况下运行EF,则可能也会出现此错误。

相关问题