我正在尝试从Windows Phone 7 Silverlight客户端消费odata feed。基本上是组和用户之间的多对多数据关系,它们之间有UserGroup表。当用户登录时,我需要使用她的UserId查询她所属的组。我的数据类如下
[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; }
}
我已经尝试了所有我知道的结果,但无论我做什么,我都会一个接一个错误。没有2个我不想做的查询,因为它太乱了,有没有解决方案?
------ ------更新
从研究的漫长夜晚,我发现odata有不支持'Any'和'All'类型查询的限制,所以我的查询目前是不可能的。我还从here发现我可以稍微修改我对poco类的实现来表示多对多的关系而不明确定义中间的类,这可能有助于我解决这个导航问题。 我仍在处理它,因为我在定义导航属性时遇到了问题,但是只要我有解决方案,我就会把它放在这里,这样它就可以帮助其他一些不幸的旅行者走上这条道路。 / p>
答案 0 :(得分:3)
最近将任何/所有支持添加到OData协议中。以下是两篇博客文章,其中包含有关OData中Any / All的一些信息:
ODTI的.NET实现,即WCF数据服务,也有Any/All support。当然,为了利用这一点,您正在与之交互的服务器必须支持Any / All。
答案 1 :(得分:1)
任何/所有问题的解决方法是使用webget在服务器端执行任何/所有过滤功能。将返回值设置为可查询,它将允许您在查询调用中使用标准odata约定和自定义筛选功能。
即。构建Web get之后的查询调用会像这样工作。
http://myServer:8000/MyService.svc/MyCustomFilteringWebGet?FilteringData=User/groups&$inlinecount=allpages
[WebGet]
public IQueryable<User> MyCustomFilteringWebGet(string FilteringData = null)
{
return //Return any/all filtered data here.
}
答案 2 :(得分:1)
所以这就是我最终为我的odata服务实现的方式。 首先,我不得不重新构建数据,取消规范化表GroupUser并在对象本身上定义相关集合:
[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; }
}
在datacontext类中,我将覆盖OnModelCreating方法,如下所示
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"));
}
这基本上使实体框架能够深入了解我希望如何定义模型,从而覆盖传统实现。我认为理解上述陈述的最简单方法是将其作为声明如下:
用户实体可以有许多(有很多)MemberOfGroups,每个都可以与'许多'GroupMembers存在(因此有多对多关系),左表(Group)的foreignkey字段应该被称为GroupId和for右表(User)应该被称为UserId,这些应该被映射到一个名为“GroupUsers”的表。
如果您查看实体框架生成的数据表,您将找到第三个名为GroupUsers的表,其中包含两列:UserId和GroupId作为组合主键,每个表引用与相应实体表的外键关系。< / p>
通过这种方式,您可以轻松查询odata服务,就好像两个集合都是相应父实体的一对多关系一样。我希望这有助于某人。