В ситуациях, когда существует два пути к таблице «Пользователь», запросы могут быть очень запутанными и приводить к результатам, аналогичным полученным для:
«Отправленный» почтовый ящик отображает имявошел в систему вместо отображения имени получателя.
Одна из вещей, которые я пытаюсь сделать перед выполнением нескольких запросов, - это попытка сгладить исходные данные запроса, чтобы сделать мои запросы более лаконичными.Примерно так:
var messages =
from ms in db.MailState
select new
{
idMail = ms.idMail,
Subject = ms.Mail.Subject,
DateSent = ms.Mail.DateSent,
Location = ms.MailLocation.Name,
Sender_idUser = ms.Mail.idSender,
Sender_DisplayName = ms.Mail.User.DisplayName,
Recipient_idUser = ms.idUser,
Recipient_DisplayName = ms.User.DisplayName,
};
Теперь, учитывая это, ваши существующие запросы будут выглядеть так:
/* Inbox */
var mailbox =
from m in messages
where m.Recipient_idUser == idUser
where m.Sender_idUser != idUser
where m.Location == mailboxType
select new
{
m.idMail,
m.Sender_DisplayName,
m.DateSent,
m.Subject
};
/* Sent */
var mailbox =
from m in messages
where m.Location == mailboxType
select new
{
m.Sender_idUser,
m.idMail,
m.DateSent,
m.Subject,
m.Recipient_DisplayName
};
Это должно быть немного проще для чтения и рассуждений.
Итак, отсюда я попытался представить записи, необходимые для представления отправки и получения электронной почты.
Допустим, у нас есть три пользователя: Анна, Билл и Бен.Если Энн отправит электронное письмо Биллу и Бену, мой messages
запрос, приведенный выше, должен будет вернуть три записи - одну для «Отправленных» в почтовом ящике Анны и одну для «Входящей почты» Билла и Бена.
Field | Anne | Bill | Ben |
----------------------+--------------+------------+------------+
idMail | 1 | 1 | 1 |
Subject | "Hi" | "Hi" | "Hi" |
DateSent | 2011/08/01 | 2011/08/01 | 2011/08/01 |
Location | "Sent Items" | "Inbox" | "Inbox" |
Sender_idUser | 1 | 1 | 1 |
Sender_DisplayName | "Anne" | "Anne" | "Anne" |
Recipient_idUser | 1 | 2 | 3 |
Recipient_DisplayName | "Anne" | "Bill" | "Ben" |
Это говорит мне о том, что данные, доступные из текущей структуры базы данных, не содержат информации, необходимой для определения того, кто является получателями для элемента в пользовательской папке «Отправленные».Фактически, это выдвигает на первый план проблему именования с полями "Recipient_ *".
Вот лучший запрос messages
, чтобы начать запросы:
var messages =
from m in db.Mail
select new
{
idMail = m.idMail,
Subject = m.Subject,
DateSent = m.DateSent,
Sender = new
{
idUser = m.idSender,
DisplayName = m.User.DisplayName,
},
Locations =
from ms in db.MailState
where ms.idMail == m.idMail
select new
{
Location = ms.MailLocation.Name,
idUser = ms.idUser,
DisplayName = ms.User.DisplayName,
},
Recipients =
from ms in db.MailState
where ms.idMail == m.idMail
where ms.idUser != m.idSender
select new
{
idUser = ms.idUser,
DisplayName = ms.User.DisplayName,
},
};
Использование этого в качестве базового запросаВаши существующие запросы теперь могут выглядеть следующим образом:
/* Inbox */
var mailbox =
from m in messages
from r in m.Recipients
where r.idUser == idUser
select new
{
m.idMail,
r.DisplayName,
m.DateSent,
m.Subject
};
/* Sent */
var mailbox =
from m in messages
where m.Sender.idUser == idUser
select new
{
m.Sender.idUser,
m.idMail,
m.DateSent,
m.Subject,
Recipients =
from r in m.Recipients
select r.DisplayName,
};
Эти запросы немного проще и должны быть очень легко обосновать их правильность или нет.
Нет необходимостиФильтруйте поле MailLocation
либо, поскольку эта информация теперь собирается в самом запросе.
Единственное, что вам нужно сделать, это сгладить поле Recipients
в одну строку для привязки данных.поскольку это набор отображаемых имен получателей, а не просто одна строка.
Надеюсь, это поможет.