3

试图在我的 EF 数据上下文实现中运行一个错误,该错误会产生一个相当神秘的错误。

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

研究该错误导致在 Google 上的点击率很少,但我发现的那些建议与我的模型关系有关,尽管在查看迁移生成的数据库时,一切似乎都是为了我的眼睛。我的相关模型如下:

我的数据上下文 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 之前运行良好,所以我怀疑项目所在的地方。

我有一个基础实体对象,我的所有东西都继承自它,它只定义了一个 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 的情况下都试过了,当我试图缩小问题范围时,我现在评论了

节点也是一个相当稀疏的类:

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

任何建议将不胜感激,我一直在努力解决这个问题。

4

3 回答 3

3

好吧,经过大量搜索我的代码并从头开始重建后,我发现问题实际上是我有一个 Node 派生类,它有一个 Uri 作为属性,显然映射失败,因为它没有默认构造函数(并且可能是其他原因)。我现在通过简单地将属性更改为我在内部验证为 Uri 的字符串来解决它,尽管我更喜欢更优雅的解决方案。我尝试将 Uri 甚至 Uri 的自定义子类(带默认构造函数)映射到复杂类型,但这没有帮助。

尽管如此,上面的问题还是得到了回答。

于 2012-11-29T12:37:06.420 回答
1

有了@Paul 的回答,我终于可以弄清楚我的问题了。

我正在使用带有继承TPT(每个类型的表)的EF 。

源代码

为了更容易,我将使用教程中描述的相同类。

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,您也可能会收到此错误。

于 2016-04-20T23:11:09.610 回答
0

我有同样的问题,不幸的是,除了与此问题相关的其他问题的答案之外,StackOverflow 中的任何解决方案都对我有用。

但是我找到了自己的解决方法,如果您遇到与我相同的问题,您也可以检查它。发生的情况是,如果某个类继承自我在 DbSet 上使用的表:

public DbSet<Employee> Employees { get; set; }

在这种情况下,如果某些其他类从我的 POCO 继承,则会Employee触发此特定错误。我从这个类中删除了所有继承,这解决了这个问题。

请注意,这个继承问题会触发同样的问题:

The given key was not present in the dictionary.

仅当继承在同一个项目上时才会发生。我试图在不同的项目上继承 POCO,它恰好很好。

于 2020-03-04T00:17:07.153 回答