Я использую Entity Framework 4.1 с POCO и DbContext, без прокси, без отложенной загрузки.
Я очень новичок в Entity Framework и LINQ, но пока очень впечатлен тем, насколько просто работать с ним.У меня есть некоторые базовые знания SQL, и я сначала создал базу данных, а затем создал модель.
Моя проблема связана с 3 таблицами (я оставил только то, что имеет отношение к делу):
CREATE TABLE [dbo].[Users](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NULL
)
CREATE TABLE [dbo].[UserFriends](
[UserId] [int] NOT NULL,
[FriendId] [int] NOT NULL
)
CREATE TABLE [dbo].[UserStatuses](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserId] [int] NOT NULL,
[Message] [nvarchar](max) NOT NULL
)
К PK относятся Usres.Id, UserStatuses.Id, UserFriends.UserId + UserFriends.FriendId.UserId также является FK для Users.Id.
У каждого пользователя может быть много статусов и много друзей
Надеюсь, структура базы данных ясна.
Что я пытаюсь сделатьсделать, это получить список пользователей, которые являются моими друзьями и их последний статус.
В SQL это будет выглядеть так:
SELECT * FROM Users U
OUTER APPLY
(
SELECT TOP 1 *
FROM UserStatuses
WHERE UserId = U.Id
ORDER BY Id DESC
) S
WHERE U.Id IN (SELECT FriendId FROM UserFriends WHERE UserId = 5)
Это получит всех друзей за '5' и их последнее сообщение о статусе.Я думаю, что это наиболее эффективный способ (внутреннее объединение для друзей и пользователей и внешнее объединение для сообщений о состоянии), но это не вопрос.
Я хотел бы сделать это с помощью структуры сущностей.Я узнал, как получить список моих друзей:
var friends = db.UserFriends.Where(f => f.FriendId.Equals(userId)).Select(f => f.User);
Но если я добавлю .Include (u => u.UserStatuses), чтобы получить статусы, я получу все их, яхотел бы вернуть только самый последний.
Единственное, что мне удалось сделать, чтобы заставить его работать, это:
var friends = db.UserFriends.Where(f => f.FriendId.Equals(userId)).Select(f => f.User);
foreach (Model.User friend in friends)
{
db.Entry(friend).Collection(f => f.UserStatuses).Query().OrderByDescending(s => s.Id).Take(1).Load();
}
Но сейчас происходит то, что происходит с каждым другомЯ генерирую еще один SQL-запрос к базе данных, это кажется (очень) плохой практикой.
Как я могу сделать это за один запрос?Буду признателен за советы по загрузке последней вставленной связанной сущности.
Спасибо,