Помощь с LINQ: смешанные объединения и указание значений по умолчанию - PullRequest
0 голосов
/ 30 мая 2010

Я пытаюсь выяснить, как сделать смешанное соединение в LINQ с определенным доступом к 2 объектам LINQ. Вот пример того, как может выглядеть фактический запрос TSQL:

SELECT
  *
FROM
  [User] AS [a]
INNER JOIN
  [GroupUser] AS [b]
ON
  [a].[UserID] = [b].[UserID]
INNER JOIN
  [Group] AS [c]
ON
  [b].[GroupID] = [c].[GroupID]
LEFT JOIN
  [GroupEntries] AS [d]
ON
  [a].[GroupID] = [d].[GroupID]
WHERE [a].[UserID] = @UserID

В конце я бы хотел перечислить объект, полный объектов GroupEntry. Что меня интересует, так это последние две таблицы / объекты в этом запросе. Я буду отображать группы как заголовок группы, а все записи под заголовком их группы. Если для группы нет записей, я все еще хочу видеть эту группу в качестве заголовка без каких-либо записей. Вот что у меня есть:

Итак, из этого я хотел бы сделать функцию:

public void DisplayEntriesByUser(int user_id)
{
    MyDataContext db = new MyDataContext();

    IEnumberable<GroupEntries> entries =
    (
        from user in db.Users
        where user.UserID == user_id
        join group_user in db.GroupUsers
          on user.UserID = group_user.UserID
        into a

        from join1 in a
        join group in db.Groups
          on join1.GroupID equals group.GroupID
        into b

        from join2 in b
        join entry in db.Entries.DefaultIfEmpty()
          on join2.GroupID equals entry.GroupID
        select entry
    );


    Group last_group_id = 0;
    foreach(GroupEntry entry in entries)
    {
        if (last_group_id == 0 || entry.GroupID != last_group_id)
        {
            last_group_id = entry.GroupID;
            System.Console.WriteLine("---{0}---", entry.Group.GroupName.ToString().ToUpper());

        }
        if (entry.EntryID)
        {
            System.Console.WriteLine("    {0}: {1}", entry.Title, entry.Text);
        }
    }
}

Пример выше работает не совсем так, как ожидалось. Есть 2 проблемы, которые мне не удалось решить:

  1. Мне все еще кажется, что я получаю ВНУТРЕННЕЕ СОЕДИНЕНИЕ вместо ЛЕВОГО СОЕДИНЕНИЯ при последнем соединении. Я не получаю пустых результатов, поэтому группы без записей не отображаются.

  2. Мне нужно найти способ, чтобы я мог заполнить значения по умолчанию для пустых наборов записей. То есть, если есть группа без записи, я хотел бы получить в основном пустую запись, за исключением того, что я бы хотел, чтобы EntryID был нулевым или 0, а GroupID - идентификатором пустой группы, которую она представляет. и мне понадобится дескриптор объекта entry.Group (т. е. его родитель, пустой объект Group).

Любая помощь по этому вопросу будет принята с благодарностью.

Примечание: имена таблиц и представление в реальном мире были получены исключительно для этого примера, но их отношения упрощают то, что я пытаюсь сделать.

Ответы [ 2 ]

0 голосов
/ 31 мая 2010
  //set this to see all queries issued.
myDC.Log = Console.Out;

  //setup to load the GroupEntries property of each group
DataLoadOptions o = new DataLoadOptions();
o.LoadWith<Group>(g => g.GroupEntries);
myDC.LoadOptions = o;

  //query to get the groups
IQueryable<Group> groupQuery =
  from g in myDC.Groups
  where g.GroupUsers.Any(gu => gu.User.UserID == user_id)
  select g;
0 голосов
/ 30 мая 2010

Это не проверено, но я думаю, что это довольно близко:

var groupEntries =   
    from
        u in db.Users
    where
        user.Id == user_id
    join
        gu in db.GroupUsers
        on u.UserId equals gu.UserId
    join
        g in db.Groups
        on gu.GroupId equals g.GroupId
    join
        ge in db.GroupEntries
        on u.GroupdId equals ge.GroupId
        into ges
    from
        ge in ges.DefaultIfEmpty(new GroupEntry { EntryId = 0, GroupId = g.GroupId })
    select
        ge;

Я не думаю, что вам нужно использовать into, если вы не планируете выполнять какую-либо дальнейшую обработку, например DefaultIfEmpty(). И обратите внимание, что вторая перегрузка DefaultIfEmpty() позволяет вам ввести пользовательское значение по умолчанию. Таким образом, вы можете создать новый объект GroupEntry и назначить нужные значения для каждого свойства (или оставить свойства пустыми).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...