尝试在我的EF datacontext实现中运行错误,这会产生相当神秘的错误。
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);
}
Blips和SensorAdapter对象在将NodeReports添加到它们之前工作正常,所以我怀疑它在那里是项目所在。
我有一个基本的Entity对象,我的所有东西都继承自对象,它只定义了类型为T的Id属性;这工作正常。
NodeReport继承自Report,其定义如下:
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:
public class NodeReport : Report
{
public virtual Node Node { get; set; }
//public virtual Blip Blip { get; set; }
}
我在有和没有Blip的情况下尝试了它,当我尝试缩小问题时注释掉了
Node也是一个非常稀疏的类:
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; }
}
任何建议都会非常感激,我一直在努力想象它。
答案 0 :(得分:3)
好吧,经过大量搜索我的代码并从头开始重建后,我发现问题实际上是我有一个派生类的Node,它有一个Uri作为属性,显然由于没有默认值而导致映射失败构造函数(可能还有其他原因)。我现在通过简单地将属性更改为我在内部验证为Uri的String来解决它,尽管我更喜欢更优雅的解决方案。我尝试将Uri甚至是Uri的自定义子类(w /默认构造函数)映射到复杂类型,但这没有帮助。
不过,上面的问题已经回答了。
答案 1 :(得分:1)
通过@Paul的回答,我终于可以找出问题所在。
我正在使用带有继承 TPT 的 EF (每种类型的表格)。
为了更容易,我将使用this教程中描述的相同类。
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");
}
请注意,我在Agency
中添加了一个名为BankAccount
的新属性。鉴于它是复杂类型,如果你没有映射它,你会在运行时遇到这个恼人的错误!
我所做的只是忽略此属性Agency
,但您也可以将其映射到EF知道该怎么做。两者都将阻止错误。
最奇怪的是,即使没有映射派生实体(BankAccount),也会出现问题。似乎EF不知何故知道你创建了派生。所以,如果你试图在没有映射某些推导的情况下运行EF,你也可能会得到这个错误。
答案 2 :(得分:0)
我遇到了同样的问题,不幸的是,除了与该问题相关的其他问题的答案之外,StackOverflow中的所有解决方案都没有对我有用。
但是我找到了自己的修复程序,如果与我的问题相同,也可以自己检查。发生的事情是,如果某个类继承自我在DbSet上使用的表:
public DbSet<Employee> Employees { get; set; }
在这种情况下,如果某些其他类从我的POCO Employee
继承,则会触发此特定错误。我从此类中删除了所有继承,从而解决了该问题。
请注意,引发此相同问题的继承问题:
The given key was not present in the dictionary.
仅当继承位于同一项目上时才会发生。我试图在其他项目上继承POCO,这很好。