title: Entity Framework relationships between different DbContext and different schemas
body: <p>So, I have two main objects, Member and Guild.  One Member can own a Guild and one Guild can have multiple Members.</p>
  
  <p>I have the Members class in a separate DbContext and separate class library.  I plan to reuse this class library in multiple projects and to help differentiate, I set the database schema to be "acc".  I have tested this library extensively and can add, delete, and update Members in the acc.Members table.</p>
  
  <p>The Guild class is as such:</p>
  
  <pre><code>public class Guild
  {
      public Guild()
      {
          Members = new List&lt;Member&gt;();
      }
  
      public int ID { get; set; }
      public int MemberID { get; set; }
      public virtual Member LeaderMemberInfo { get; set; }
      public string Name { get; set; }
      public virtual List&lt;Member&gt; Members { get; set; }
  }
  </code></pre>
  
  <p>with a mapping of:</p>
  
  <pre><code>internal class GuildMapping : EntityTypeConfiguration&lt;Guild&gt;
  {
      public GuildMapping()
      {
          this.ToTable("Guilds", "dbo");
          this.HasKey(t =&gt; t.ID);
          this.Property(t =&gt; t.MemberID);
          this.HasRequired(t =&gt; t.LeaderMemberInfo).WithMany().HasForeignKey(t =&gt; t.MemberID);
          this.Property(t =&gt; t.Name);
          this.HasMany(t =&gt; t.Members).WithMany()
              .Map(t =&gt;
              {
                  t.ToTable("GuildsMembers", "dbo");
                  t.MapLeftKey("GuildID");
                  t.MapRightKey("MemberID");
              });
      }
  }
  </code></pre>
  
  <p>But, when I try to create a new Guild, it says that there is no dbo.Members.</p>
  
  <p>I got reference to the Member's EF project and added the mapping to the Members class to the DbContext that the Guild class is a part of.  <code>modelBuilder.Configurations.Add(new MemberMapping());</code>
  (Not sure if that is the best way.)</p>
  
  <p>This resulted with this error:</p>
  
  <pre><code>{"The member with identity 'GuildProj.Data.EF.Guild_Members' does not exist in the metadata collection.\r\nParameter name: identity"}
  </code></pre>
  
  <p>How can I utilize the foreign key between these two tables cross DbContexts and with different database schemas?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I narrowed down the cause of the error.  When I create a new guild, I set the guild leader's Member ID to MemberID.  This works fine.  But, when I then try to add that leader's Member object to the Guild's List of Members (Members), that's what causes the error.</p>
  
  <p><strong>UPDATE 2</strong></p>
  
  <p>Here is the code of how I create the Context that the Guild class is in.  (As requested by Hussein Khalil)</p>
  
  <pre><code>public class FSEntities : DbContext
  {
      public FSEntities()
      {
          this.Configuration.LazyLoadingEnabled = false;
          Database.SetInitializer&lt;FSEntities&gt;(null);
      }
  
      public FSEntities(string connectionString)
          : base(connectionString)
      {
      }
  
      protected override void OnModelCreating(DbModelBuilder modelBuilder)
      {
          modelBuilder.Configurations.Add(new GuildMapping());
          modelBuilder.Configurations.Add(new KeyValueMappings());
          modelBuilder.Configurations.Add(new LocaleMappings());
  
          modelBuilder.Configurations.Add(new MemberMapping());
      }
  
      public DbSet&lt;Guild&gt; Guilds { get; set; }
      public DbSet&lt;KeyValue&gt; KeyValues { get; set; }
      public DbSet&lt;Locale&gt; Locales { get; set; }
  }
  </code></pre>
  
  <p>This is how I am saving it in the repo:</p>
  
  <pre><code>    public async Task CreateGuildAsync(Guild guild)
      {
          using (var context = new FSEntities(_ConnectionString))
          {
              context.Entry(guild.Members).State = EntityState.Unchanged;
              context.Entry(guild).State = EntityState.Added;
              await context.SaveChangesAsync();
          }
      }
  </code></pre>
  
  <p><strong>FINAL RESOLUTION</strong></p>
  
  <p>So, I had to add mappings to <code>Member</code>, <code>Role</code>, and <code>Permission</code> in DbContext that contained <code>Guild</code>.  I had to add Role and Permission because Member had <code>List&lt;Role&gt; Roles</code> and each Role had <code>List&lt;Permission&gt; Permissions</code>.</p>
  
  <p>This got me closer to the solution.  I was still getting errors like:</p>
  
  <pre><code>{"The member with identity 'GuildProj.Data.EF.Member_Roles' does not exist in the metadata collection.\r\nParameter name: identity"}
  </code></pre>
  
  <p>Here, when you pull Member from the <code>Session</code>, you get something like this:</p>
  
  <pre><code>System.Data.Entity.DynamicProxies.Member_FF4FDE3888B129E1538B25850A445893D7C49F878D3CD40103BA1A4813EB514C
  </code></pre>
  
  <p>Entity Framework does not seem to play well with this.  Why?  I am not sure, but I think it is because ContextM creates a proxy of Member and by cloning the Member into a new Member object, ContextM no longer has association.  This, I think, allows ContextG to use the new Member object freely.  I tried setting ProxyCreationEnabled = false in my DbContexts, but the Member object being pulled out of Session kept being of type System.Data.Entity.DynamicProxies.Member.</p>
  
  <p>So, what I did was:</p>
  
  <pre><code>Member member = new Member((Member)Session[Constants.UserSession]);
  </code></pre>
  
  <p>I had to clone each <code>Role</code> and each <code>Permission</code> as well inside their respective constructors.</p>
  
  <p>This got me 99% of the way there.  I had to alter my repo and how I was saving the <code>Guild</code> object.</p>
  
  <pre><code>            context.Entry(guild.LeaderMemberInfo).State = EntityState.Unchanged;
              foreach(var member in guild.Members)
              {
                  context.Entry(member).State = EntityState.Unchanged;
              }
              context.Entry(guild).State = EntityState.Added;
              await context.SaveChangesAsync();
  </code></pre>