2012-07-16 21 views
7

.NET 4.0ソリューションでEntity Frameworkを数週間使用しています。 EF 4.3.1です。最初にデータベーススキーマを作成し、 "EF4.x DbContext Generator"テンプレートを使用してエンティティオブジェクトを生成しました。Entity Framework 4.3.1でエンティティタイプのフィールド/プロパティを設定できません

私はスキーマ内に3つのテーブルを持っていましたが、すべて単純なCRUDメソッドでうまくいきました。

SourceUriに0件の件名があり、件名に正確に1件のSourceUriが存在するように、既存のテーブル「SourceUri」への外部キー参照を持つ「件名」テーブルを追加しました。

edmxモデルを更新しましたが、正しく表示されました。しかし、関係なく、私がしようとするもの、私は次の操作を行うように見えることはできません。

  • 新しいSourceUriレコード
  • これはコードIで新しいSourceUri
  • のための1つまたは複数の被験者

を追加します現在試しています。コンテキストを定期的に保存しているのが分かりますが、もともとは、メソッドの最後に一度だけ変更を保存していました。

/// <summary> 
    /// Adds a new Source URI to the system 
    /// </summary> 
    /// <param name="sourceUri">The source URI to add</param> 
    /// <param name="subjectNames">List of subjects for this source URI, in order</param> 
    /// <returns>The added source URI</returns> 
    public SourceUri AddSourceUri(SourceUri sourceUri, IList<string> subjectNames) 
    { 
     try 
     { 
      _logger.Debug("Adding new source URI '{0}', with '{1}' subjects.", sourceUri.Uri, 
       subjectNames != null ? subjectNames.Count : 0); 
      LogSourceUriDetails(sourceUri, "Adding"); 

      using (var dbContext = GetDbContext()) 
      { 
       dbContext.SourceUris.Add(sourceUri); 
       dbContext.SaveChanges(); // this save succeeds 

       // add the subjects if there are any 
       if (subjectNames != null) 
       { 
        for (int i = 0; i < subjectNames.Count; i++) 
        { 
         Subject newSubject = new Subject() 
               { 
                DisplayOrder = i, 
                SourceUriId = sourceUri.SourceUriId, 
                SubjectText = subjectNames.ElementAt(i).Trim() 
               }; 
         _logger.Debug("Adding new subject '{0}' to source URI '{1}'.", newSubject.SubjectText, 
             sourceUri.Uri); 
         dbContext.Subjects.Add(newSubject); // this line fails 
         dbContext.SaveChanges(); 
        } 
       } 

       _logger.Debug("Successfully added new source URI '{0}' with '{1}' subjects. Source URI ID is '{2}'.", 
        sourceUri.Uri, subjectNames != null ? subjectNames.Count : 0, sourceUri.SourceUriId); 
       return sourceUri; 
      } 
     } 
     catch (Exception exception) 
     { 
      _logger.ErrorException(string.Format("An error occurred adding new source URI '{0}' with '{1}' subjects.", 
       sourceUri.Uri, subjectNames != null ? subjectNames.Count : 0), exception); 
      throw; 
     } 
    } 

コードは、新しいSourceUriを追加し、変更を保存します。ただし、データコンテキストに新しいSubjectを追加することはできません。その変更を保存しようとする限りは得られません。

例外は次のとおりです。

Unable to set field/property Subjects on entity type CommentService.DomainObjects.SourceUri. See InnerException for details. 
System.Data.Objects.Internal.PocoPropertyAccessorStrategy.CollectionRemove(RelatedEnd relatedEnd, Object value) 
System.Data.Objects.Internal.EntityWrapper`1.CollectionRemove(RelatedEnd relatedEnd, Object value) 
System.Data.Objects.DataClasses.EntityCollection`1.RemoveFromObjectCache(IEntityWrapper wrappedEntity) 
System.Data.Objects.DataClasses.RelatedEnd.Remove(IEntityWrapper wrappedEntity, Boolean doFixup, Boolean deleteEntity, Boolean deleteOwner, Boolean applyReferentialConstraints, Boolean preserveForeignKey) 
System.Data.Objects.DataClasses.RelatedEnd.FixupOtherEndOfRelationshipForRemove(IEntityWrapper wrappedEntity, Boolean preserveForeignKey) 
System.Data.Objects.DataClasses.RelatedEnd.Remove(IEntityWrapper wrappedEntity, Boolean doFixup, Boolean deleteEntity, Boolean deleteOwner, Boolean applyReferentialConstraints, Boolean preserveForeignKey) 
System.Data.Objects.DataClasses.EntityReference`1.Exclude() 
System.Data.Objects.DataClasses.RelationshipManager.RemoveRelatedEntitiesFromObjectStateManager(IEntityWrapper wrappedEntity) 
System.Data.Objects.ObjectContext.AddObject(String entitySetName, Object entity) 
System.Data.Entity.Internal.Linq.InternalSet`1.&lt;&gt;c__DisplayClass5.&lt;Add&gt;b__4() 
System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName) 
System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity) 
System.Data.Entity.DbSet`1.Add(TEntity entity) 
CommentService.Business.Managers.SourceUriManager.AddSourceUri(SourceUri sourceUri, IList`1 subjectNames) in C:\Projects\SVN Misc Projects\CommentService\trunk\CommentService.Business\Managers\SourceUriManager.cs:line 152 
CommentService.Web.Comment.AddSourceUri(SourceUri sourceUri, IList`1 subjectNames) in C:\Projects\SVN Misc Projects\CommentService\trunk\CommentService.Web\Comment.svc.cs:line 173 
SyncInvokeAddSourceUri(Object , Object[] , Object[]) 
System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp; outputs) 
System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc) 
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc) 
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc&amp; rpc) 
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&amp; rpc) 
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc) 
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc&amp; rpc) 
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&amp; rpc) 
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc) 
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&amp; rpc) 
System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet) 

私はこの上でのラウンドとラウンドを行っている、といくつかのわずかに異なる例外を見てきました。それらはすべて、SourceUriオブジェクトのSubjectナビゲーションプロパティが何らかの形で読み取り専用または固定長(配列?)であるという事実を指しているようです。次のように

生成されたエンティティクラスは、見て:

//------------------------------------------------------------------------------ 
// <auto-generated> 
// This code was generated from a template. 
// 
// Manual changes to this file may cause unexpected behavior in your application. 
// Manual changes to this file will be overwritten if the code is regenerated. 
// </auto-generated> 
//------------------------------------------------------------------------------ 

namespace CommentService.DomainObjects 
{ 
    using System; 
    using System.Collections.Generic; 

    public partial class SourceUri 
    { 
     public SourceUri() 
     { 
      this.Comments = new HashSet<Comment>(); 
      this.Subjects = new HashSet<Subject>(); 
     } 

     public long SourceUriId { get; set; } 
     public string Uri { get; set; } 
     public string Description { get; set; } 
     public System.DateTime DateCreated { get; set; } 
     public string AdminUser { get; set; } 

     public virtual ICollection<Comment> Comments { get; set; } 
     public virtual ICollection<Subject> Subjects { get; set; } 
    } 
} 


//------------------------------------------------------------------------------ 
// <auto-generated> 
// This code was generated from a template. 
// 
// Manual changes to this file may cause unexpected behavior in your application. 
// Manual changes to this file will be overwritten if the code is regenerated. 
// </auto-generated> 
//------------------------------------------------------------------------------ 

namespace CommentService.DomainObjects 
{ 
    using System; 
    using System.Collections.Generic; 

    public partial class Subject 
    { 
     public Subject() 
     { 
      this.Comments = new HashSet<Comment>(); 
     } 

     public long SubjectId { get; set; } 
     public long SourceUriId { get; set; } 
     public string SubjectText { get; set; } 
     public int DisplayOrder { get; set; } 

     public virtual ICollection<Comment> Comments { get; set; } 
     public virtual SourceUri SourceUri { get; set; } 
    } 
} 

はなぜこの仕事をしますか?

物事のクイックリストのI /しようとしたチェックしました:

  • データベーススキーマが正しいに見える - SQLおよび主キーと予想通り、私はレコードを挿入することができ、外部キーとアイデンティティが正しく
  • を行動しているように
  • モデルには、PKアイデンティティ(EntityKey = true、StoreGeneratedPattern = Identity)を含むデータベーススキーマが正しく反映されているようです。
  • EFを使用してスキーマにデータを保持することができましたが、データを挿入した後に例外がスローされます。コンテキストが同期していない可能性があることを示していますSourceUriオブジェクトのサブジェクトナビゲーションプロパティを更新する
  • サブジェクトをdbContext.Subjectsコレクションに追加しようとしましたが、SourceUri.Subjectsコレクションにも追加しようとしました。 SubjectのSourceUriIdプロパティの代わりにSubjectのSourceUriプロパティを設定しようとしました。
+0

「*詳細についてのInnerExceptionを参照してください」*最初に言いますスタックトレースの行。あなたはそれを行い、あなたの質問に内部例外メッセージを追加できますか? – Slauma

+0

内部例外はnullです。 –

答えて

14

私はこの問題の一番下にいます。問題の動作は、WCF Webサービス経由でメソッドに渡されるSourceUriエンティティによって発生していました。これは、オブジェクトのICollectionプロパティが、長さが固定長であり、追加できない配列としてデシリアライズされていることを意味していました。次のようにコレクションは明示的なクラスを生成するように私は私のエンティティを生成したテンプレートを変更することによってこの問題を解決してきた

は、一覧表示されます:

//------------------------------------------------------------------------------ 
// <auto-generated> 
// This code was generated from a template. 
// 
// Manual changes to this file may cause unexpected behavior in your application. 
// Manual changes to this file will be overwritten if the code is regenerated. 
// </auto-generated> 
//------------------------------------------------------------------------------ 

namespace CommentService.DomainObjects 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; // added this 

    public partial class SourceUri 
    { 
     public SourceUri() 
     { 
      this.Comments = new HashSet<Comment>().ToList(); // added this 
      this.Subjects = new HashSet<Subject>().ToList(); // added this 
     } 

     public long SourceUriId { get; set; } 
     public string Uri { get; set; } 
     public string Description { get; set; } 
     public System.DateTime DateCreated { get; set; } 
     public string AdminUser { get; set; } 

     public virtual List<Comment> Comments { get; set; } // altered these to List 
     public virtual List<Subject> Subjects { get; set; } // altered these to List 
    } 
} 
関連する問題