I have an Organization class and a User class as follows, & 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 & AddressOrganization, AddressAnything, etc. The reason being is I may have multiple entities that I want to assign an Address to & don't want an in-between join table for every single entity that needs an Address record.
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.
Is there a way Fluent API or Code-First Data Annotations can accommodate some sort of composite generic foreign key with an object type?
Like a DomainObjectType table?
DomainObjectType:
public class DomainObjectType
{
[Key]
public int Id { get; set; } // seeded
public string ObjectType { get; set; } // User or Organization
}
DomainObjectType would be seeded with:
var objTypes = new List<DomainObjectType>
{
new DomainObjectType() { Id = 1, ObjectType = "User" },
new DomainObjectType() { Id = 2, ObjectType = "Organization" }
};
objTypes.ForEach(c => context.DomainObjectTypes.Add(c));
context.SaveChanges();
Organization:
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<User> Users { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
#endregion
}
User
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<Address> Addresses { get; set; }
}
Address
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<Organization> Organizations { get; set; }
public virtual ICollection<User> Users { get; set; }
#endregion
}
Fluent API stuff:
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<PluralizingTableNameConvention>();
// one-to-many Organization-to-Users
modelBuilder.Entity<User>()
.HasRequired(u => u.Organization)
.WithMany(o => o.Users)
.HasForeignKey(u => u.OrganizationId);
// what goes here for generic AddressDomainObjectType?
}