So, here is how I was eventually implemented for my odata service. First, I had to redo the data, excluding the GroupUser normalization table and defining the appropriate assembly for the objects themselves:
[DataServiceKey("Id")] public class Group { public Guid Id { get; set; } public string GroupTag { get; set; } public DateTime DateCreated { get; set; } [ForeignKey("GroupOwner")] public Guid? GroupOwnerId { get; set; } public virtual Person GroupOwner { get; set; } public bool IsActive { get; set; } //his represents the many-to-many relationship public virtual ICollection<User> GroupMembers { get; set; } } [DataServiceKey("Id")] public class User { public Guid Id { get; set; } public string Username { get; set; } public string Password { get; set; } //This represents the many-to-many relationship public virtual ICollection<Group> MembersOfGroups { get; set; } //This represents the 'GroupOwner' ForeignKey relationship public virtual ICollection<Group> MyGroups { get; set; } }
In the datacontext class, I then override the OnModelCreating method as follows
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<User>().HasMany(p => p.MemberOfGroups). WithMany(c => c.GroupMembers) .Map(t=>t.MapLeftKey("GroupId") .MapRightKey("UserId") .ToTable("GroupUsers")); }
This basically gives the entity infrastructure some insight into how I want my model to be defined, thereby overriding the usual implementation. The easiest way, in my opinion, to understand the above statement is to read it as an expression as follows:
A user object can have many (has many) MemberOfGroups, each of which can exist "with many" GroupMembers members (hence many of many), the foreignkey field for the left table (Group) should be called GroupId and for the right table (User) should be called UserId, and they must be mapped to the "GroupUsers" table.
If you look at the data tables generated by the entity framework, you will find a third table named GroupUsers with two columns: UserId and GroupId as a combined primary key and each referencing a foreign key relationship with the corresponding entity table.
With this, you can easily request your odata service, as if both collections were from one to many relationships of the corresponding parent. Hope this helps someone.
source share