Многие ко многим запрос из канала OData - PullRequest
4 голосов
/ 26 марта 2012

Я пытаюсь использовать поток данных из клиента Windows Phone 7 Silverlight.В основном это отношение данных «многие ко многим» между группами и пользователями с таблицей групп пользователей между ними.Когда пользователь входит в систему, мне нужно запросить группы, к которым он принадлежит, используя его 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; }
}

Я перепробовал все, что я знаю, чтобы получить этот результат, но я продолжаю получать одну ошибку за другой, независимо от того, что я делаю.Если не считать двух запросов, которые я не хочу делать, потому что это было бы слишком грязно, есть ли какое-нибудь решение?

------ Обновление ------

После долгой ночи исследований я обнаружил, что у одататы есть ограничение не поддерживать запросы типа «Любой» и «Все», поэтому мой запрос в настоящее время будет невозможен.Что я также обнаружил из здесь , что моя реализация классов poco может быть слегка изменена, чтобы представлять отношение многие ко многим, без явного определения класса в середине, что потенциально поможет мне решить эту проблему навигации.Я все еще нахожусь в процессе его разработки, поскольку у меня возникают проблемы с определением свойств навигации, но как только у меня появится решение, я поставлю его здесь, чтобы оно могло помочь другому незадачливому путешественнику, который идет по этому пути.

Ответы [ 3 ]

3 голосов
/ 26 марта 2012

Любая / Вся поддержка была добавлена ​​в протокол OData недавно. Вот два сообщения в блоге с некоторой информацией о Any / All в OData:

Поддержка любых и всех

Еще больше, чем когда-либо

.NET-реализация OData, WCF Data Services, также имеет Любая / Все поддержка . Конечно, чтобы воспользоваться этим, сервер, с которым вы взаимодействуете, должен поддерживать Any / All.

1 голос
/ 30 марта 2012

Итак, вот как я в конечном итоге реализовал свою службу 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, а для правой таблицы (User) должно называться UserId, и они должны отображаться в таблице с именем «GroupUsers».

Если вы посмотрите на таблицы данных, сгенерированные структурой сущностей, вы найдете третью таблицу под названием GroupUsers с двумя столбцами: UserId и GroupId как объединенный первичный ключ, и каждая ссылается на отношение внешнего ключа с соответствующей таблицей сущностей.

При этом вы можете легко запросить службу оддаты, как если бы обе коллекции были отношениями один-ко-многим соответствующей родительской сущности.Надеюсь, это кому-нибудь поможет.

1 голос
/ 26 марта 2012

Обходной путь для любой / всех проблем заключается в использовании веб-виджета для выполнения любых / всех функций фильтрации на стороне сервера.Если возвращаемое значение задано как запрашиваемое, это позволит вам использовать стандартные соглашения об одатах наряду с пользовательскими функциями фильтрации в вызове запроса.

т.е. вызов запроса после создания веб-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. 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...