I’m trying to consume an odata feed from a windows phone 7 silverlight client. Basically is a Many to many data relationship between Groups and Users with a UserGroup table between them. When a User logs in, I need to query for the groups she belongs to using her UserId. My Data classes are as follows
[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; }
public virtual ICollection<GroupUser> GroupUsers { get; set; }
}
[DataServiceKey("Id")]
public class GroupUser
{
public Guid Id { get; set; }
[ForeignKey("Group")]
public Guid GroupId { get; set; }
public virtual Group Group { get; set; }
[ForeignKey("Person")]
public Guid PersonId { get; set; }
public virtual Person Person { get; set; }
public bool IsActive { get; set; }
}
[DataServiceKey("Id")]
public class User
{
public Guid Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public virtual ICollection<GroupUser> UserGroups { get; set; }
public virtual ICollection<Group> MyGroups { get; set; }
}
I have tried everything I know to get this result but I keep getting one error after the other no matter what I do. Short of having 2 queries which I don’t want to do because it would be too messy, is there any solution?
——Update——
From the long night of research, I have discovered that odata has the limitation of not supporting ‘Any’ and ‘All’ type queries, so my query would not be possible at this time. What I also discovered from here that my implementation of the poco classes could be slightly modified to represent a many to many relationship without explicitly defining the class in the middle which would potentially help me solve this navigation problem.
I am still in the process of working it out as I am having issues defining the navigation properties but as soon as I have a solution, I’ll put it up here so it can help some other hapless traveler who comes down this path.
So here is how I eventually implemented for my odata service.
First I had to remodel the data eliminating the normalization table GroupUser and defining the related collection on the objects themselves:
In the datacontext class, I then override the OnModelCreating method as follows
This basically gives the entity framework some insight into how I want my model defined, thus overriding the conventional implementation. The easiest way in my opinion to understand the above statement is to read it as a statement as follows:
The User entity can have many (has many) MemberOfGroups, each of which can exist ‘with many’ GroupMembers (hence the many to many relationship), the foreignkey field for the left table (Group) should be called GroupId and for the right table (User) should be called UserId and these should be Mapped to a table called “GroupUsers”.
If you take a look at the data tables generated by entity framework, you will find a third table called GroupUsers with two columns : UserId and GroupId as combined primary key and each referencing a foreign key relationship with the corresponding entity table.
With this, you can easily query your odata service as if both collections were one to many relationships of the corresponding parent entity. I hope this helps someone.