【问题标题】:Many to many query from OData feed来自 OData 源的多对多查询
【发布时间】:2012-03-25 21:40:09
【问题描述】:

我正在尝试使用来自 windows phone 7 silverlight 客户端的 odata 提要。基本上是组和用户之间的多对多数据关系,它们之间有一个 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; }
}

我已经尝试了我所知道的一切来获得这个结果,但无论我做什么,我都会一个接一个地收到一个错误。缺少两个我不想做的查询,因为它太乱了,有什么解决办法吗?

--------更新-----

通过一夜的研究,我发现odata有不支持'Any'和'All'类型查询的限制,所以我的查询暂时无法进行。我还从here 发现,我的 poco 类的实现可以稍微修改以表示多对多关系,而无需在中间显式定义类,这可能有助于我解决这个导航问题。 我仍在解决它,因为我在定义导航属性时遇到问题,但是一旦我有解决方案,我就会把它放在这里,这样它可以帮助其他一些走这条路的倒霉旅行者。

【问题讨论】:

  • 您希望得到什么结果?
  • 嗨 CasperOne,我希望提供一个 UserId 并获取用户所属的组列表。

标签: .net linq odata


【解决方案1】:

最近向 OData 协议添加了任何/所有支持。以下是两篇博文,其中包含有关 OData 中的 Any/All 的一些信息:

Support for Any and All

Even More Any and All

OData 的 .NET 实现,即 WCF 数据服务,也有 Any/All support。当然,为了利用这一点,您与之交互的服务器必须支持 Any/All。

【讨论】:

  • Odata.org 博客链接已关闭。你能发布更多信息吗?
【解决方案2】:

any/all 问题的解决方法是使用 webget 在服务器端执行 any/all 过滤功能。将返回值设置为可查询,它将允许您在查询调用中使用标准 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. 
}

【讨论】:

  • 这看起来不错,我会试一试并返回结果。谢谢!
【解决方案3】:

这就是我最终为我的 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"));

    }

这基本上让实体框架对我希望如何定义我的模型有了一些了解,从而覆盖了传统的实现。在我看来,理解上述陈述的最简单方法是将其解读为如下陈述:

User 实体可以有很多(有很多)MemberOfGroups,每一个都可以“与很多”GroupMembers 存在(因此是多对多关系),左表(Group)的外键字段应该称为 GroupId,对于正确的表(用户)应称为 UserId,这些应映射到名为“GroupUsers”的表。

如果您查看实体框架生成的数据表,您会发现第三个表名为 GroupUsers,其中包含两列:UserId 和 GroupId 作为组合主键,并且每个都与对应的实体表引用外键关系。

有了这个,您可以轻松地查询您的 odata 服务,就好像两个集合都是相应父实体的一对多关系一样。我希望这对某人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    • 2017-01-19
    • 2011-02-25
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多