title: Fluent API Composite Foreign Key with Generic Object Type
body: <p>I have an Organization class and a User class as follows, &amp; I want to be able to assign an Address to each individually - without having the need for two separate many-to-many tables for AddressUser &amp; AddressOrganization, AddressAnything, etc.  The reason being is I may have multiple entities that I want to assign an Address to &amp; don't want an in-between join table for every single entity that needs an Address record.</p>
  
  <p>I also don't want to store a foreign keys like Address.OrganizationId or Address.UserId for each entity that needs an address associated with it.</p>
  
  <p>Is there a way Fluent API or Code-First Data Annotations can accommodate some sort of composite generic foreign key with an object type?</p>
  
  <p>Like a DomainObjectType table?</p>
  
  
  
  <p><strong>DomainObjectType:</strong></p>
  
  <pre class="lang-cs prettyprint-override"><code>public class DomainObjectType
  {
      [Key]
      public int Id { get; set; } // seeded
  
      public string ObjectType { get; set; } // User or Organization
  }
  </code></pre>
  
  <p>DomainObjectType would be seeded with:</p>
  
  <pre class="lang-cs prettyprint-override"><code>var objTypes = new List&lt;DomainObjectType&gt;
    { 
        new DomainObjectType() { Id = 1, ObjectType = "User" },
        new DomainObjectType() { Id = 2, ObjectType = "Organization" }
    };
  objTypes.ForEach(c =&gt; context.DomainObjectTypes.Add(c));
  context.SaveChanges();
  </code></pre>
  
  <p><strong>Organization:</strong></p>
  
  <pre class="lang-cs prettyprint-override"><code>public class Organization
      {    
          // Primary key
          [Key]
          public int Id { get; set; }
          public string Name { get; set; }
          public string Description { get; set; }
  
          #region Navigation Properties
  
          public virtual ICollection&lt;User&gt; Users { get; set; }
          public virtual ICollection&lt;Address&gt; Addresses { get; set; }
  
          #endregion
  
      }
  </code></pre>
  
  <p><strong>User</strong></p>
  
  <pre class="lang-cs prettyprint-override"><code>public class User
  {
      [Key]
      public int Id { get; set; }
      public string FirstName { get; set; }
      public string LastName { get; set; }
      public int OrganizationId { get; set; }
  
      [ForeignKey("OrganizationId")]
      public virtual Organization Organization { get; set; }
      public virtual ICollection&lt;Address&gt; Addresses { get; set; }
  }
  </code></pre>
  
  <p><strong>Address</strong></p>
  
  <pre class="lang-cs prettyprint-override"><code>public class Address
  {
      // Primary Key
      public int Id { get; set; }
      public string Address1 { get; set; }
      public string Address2 { get; set; }
      public string City { get; set; }
      public string State { get; set; }
      public string Zip { get; set; }
      public string AddressType { get; set; }
  
      #region Foreign Keys
  
      // not completely sure about this? (maybe move to many-to-many "join" table)
      public int DomainObjectId { get; set; } // Composite key; would be either an OrganizationId or UserId
      public string DomainObjectTypeId { get; set; } // Composite key
  
      #endregion
  
      #region Navigation Properties
  
      public virtual ICollection&lt;Organization&gt; Organizations { get; set; }
      public virtual ICollection&lt;User&gt; Users { get; set; }
  
      #endregion
  
  }
  </code></pre>
  
  <p><strong>Fluent API stuff:</strong></p>
  
  <pre class="lang-cs prettyprint-override"><code>protected override void OnModelCreating(DbModelBuilder modelBuilder)
      {
          // Configure Code First to ignore PluralizingTableName convention
          // If you keep this convention then the generated tables will have pluralized names.
          modelBuilder.Conventions.Remove&lt;PluralizingTableNameConvention&gt;();
  
          // one-to-many Organization-to-Users
          modelBuilder.Entity&lt;User&gt;()
              .HasRequired(u =&gt; u.Organization)
              .WithMany(o =&gt; o.Users)
              .HasForeignKey(u =&gt; u.OrganizationId);
  
          // what goes here for generic AddressDomainObjectType?
      }
  </code></pre>