Unable to set field/property on entity type with Entity Framework 4.3.1
===

I have been using Entity Framework in a .NET 4.0 solution for a few weeks. It is EF 4.3.1. I have created the database schema first, and generated my Entity Objects using "EF4.x DbContext Generator" template.

I had three tables in the schema and it was all working fine with simple CRUD methods.

I have now added a fourth table, "Subjects", which has a foreign Key reference to an existing table "SourceUri", such that a SourceUri can have 0-many subjects, and a Subject has exactly one SourceUri.

I have updated my edmx model and it looks correct. However, no matter what I try, I cannot seem to do the following:

 - Add a new SourceUri record
 - Add one or more Subjects for the new SourceUri

This is the code I am currently trying. You can see I am saving the context regularly, but originally I was only saving the changes once at the end of the method.

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

The code adds the new SourceUri and saves the changes. However, it does not manage to add the new Subject to the data context. It does not get as far as trying to save that change.

The exception is:

    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)


I have gone round and round on this, and have seen several slightly different exceptions. They all seem to point to the fact that the Subjects navigation property of the SourceUri object is in some way read-only or fixed length (array?).

The generated entity classes look as follows:

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


Why doesn't this work?

Quick list of things I've checked/tried:

 - The database schema looks correct - I can insert records as expected with SQL and primary keys, foreign keys and identities seem to be behaving correctly
 - The model seems to reflect the database schema correctly, including PK identities (EntityKey = true, StoreGeneratedPattern=Identity)
 - I have managed to get EF to persist data into my schema, but after the data is inserted, an exception is thrown stating that the context might be out of sync - again pertaining to not being able to update the Subjects navigation property of the SourceUri object
 - I have tried adding the Subjects to the dbContext.Subjects collection, and also to the SourceUri.Subjects collection. I have also tried setting the Subject's SourceUri property instead of the Subject's SourceUriId property.

