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 でヒットすることはほとんどありませんでしたが、移行によって生成された DB を見ると、私の目にはすべて問題ないように見えますが、私が見つけたものは、私のモデル関係で何かを行うことを示唆していました。私の関連モデルは次のとおりです。

私のデータ コンテキスト 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; }
    }

そこにブリップがある場合とない場合の両方で試してみましたが、問題を絞り込もうとしているときにコメントアウトしました

ノードは、現時点でもかなりまばらなクラスです。

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

さて、私のコードを何度も検索してゼロから再構築した後、問題は実際には Uri をプロパティとして持つ Node の派生クラスがあり、デフォルトのコンストラクターがないため明らかにマッピングに失敗したことであることがわかりました (そしておそらく他の理由)。私は今のところ、プロパティを Uri として内部的に検証する String に変更するだけで解決しましたが、より洗練された解決策をお勧めします。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");
}

問題

Agency内にという新しいプロパティを追加したことに注意してくださいBankAccount複雑な型であるため、マップしないと、実行時にこの厄介なエラーが発生します!

解決

私がしたことは、単にこのプロパティAgencyを無視することでしたが、何をすべきかを知っている EF にマップすることもできます。どちらもエラーを停止します。

最も奇妙なことは、派生エンティティ (BankAccount) をマッピングしなくても問題が発生することです。EF は、あなたが派生物を作成したことを何らかの形で知っているようです。そのため、派生をマッピングせずに EF を実行しようとすると、おそらくこのエラーも発生します。

于 2016-04-20T23:11:09.610 に答える