Как загрузить Многих во многий запрос LINQ?

6
задан 17 September 2008 в 04:20
поделиться

5 ответов

Yay! Это работало.

Если у кого-либо есть та же проблема, вот то, что я сделал:

public IList<Post> GetPosts(int page, int record)
{
    var options = new DataLoadOptions();
    options.LoadWith<Post>(p => p.PostTags);
    options.LoadWith<PostTag>(pt => pt.Tag);
    using (var db = new DatabaseDataContext(m_connectionString))
    {
        var publishDateGmt = (from p in db.Posts
                              where p.Status != PostStatus.Hidden
                              orderby p.PublishDateGmt descending
                              select p.PublishDateGmt)
                              .Skip(page * record)
                              .Take(record)
                              .ToList()
                              .Last();
        db.LoadOptions = options;
        return (from p in db.Posts
                where p.Status != PostStatus.Closed 
                    && p.PublishDateGmt >= publishDateGmt
                orderby p.PublishDateGmt descending
                select p)
                .Skip(page * record)
                .ToList();
    }
}

Это выполняет только два запроса и загружает все теги для каждого сообщения.

Идея состоит в том, чтобы заставить некоторое значение ограничивать запрос в последнем сообщении, в котором мы нуждаемся (в этом случае, столбец PublishDateGmt будет достаточен), и затем ограничьте второй запрос с тем значением вместо Взятия ().

Спасибо за Ваш сирокко справки.

2
ответ дан 17 December 2019 в 07:10
поделиться

Это немного странно потому что

DataLoadOptions o = new DataLoadOptions ( );
o.LoadWith<Listing> ( l => l.ListingStaffs );
o.LoadWith<ListingStaff> ( ls => ls.MerchantStaff );
ctx.LoadOptions = o;

IQueryable<Listing> listings = (from a in ctx.Listings
            where a.IsActive == false 
                            select a);
List<Listing> list = listings.ToList ( );

результаты в запросе как:

SELECT [t0].*, [t1].*, [t2].*, (
SELECT COUNT(*)
FROM [dbo].[LStaff] AS [t3]
INNER JOIN [dbo].[MStaff] AS [t4] ON [t4].[MStaffId] = [t3].[MStaffId]
WHERE [t3].[ListingId] = [t0].[ListingId]
) AS [value]
FROM [dbo].[Listing] AS [t0]
LEFT OUTER JOIN ([dbo].[LStaff] AS [t1]
INNER JOIN [dbo].[MStaff] AS [t2] ON [t2].[MStaffId] = [t1].[MStaffId]) ON 
[t1].[LId] = [t0].[LId] WHERE NOT ([t0].[IsActive] = 1) 
ORDER BY [t0].[LId], [t1].[LStaffId], [t2].[MStaffId]

(Я сократил имена и добавил * на выборе).

Таким образом, это, кажется, делает выбор хорошо.

1
ответ дан 17 December 2019 в 07:10
поделиться

Я ответил на это в другом сообщении: О нетерпеливой загрузке. В Вашем случае это, вероятно, было бы что-то как:

DataLoadOptions options = new DataLoadOptions();    
options.LoadWith<Post>(p => p.PostTag);
options.LoadWith<PostTag>(pt => pt.Tag); 

Хотя быть осторожным - DataLoadOptions должен быть установлен, ПРЕЖДЕ ЧЕМ ЛЮБОЙ запрос отправляется в базу данных - в противном случае, исключение выдается (никакая идея, почему он похож, это в Linq2Sql - вероятно, будет зафиксировано в более поздней версии).

0
ответ дан 17 December 2019 в 07:10
поделиться

Я сожалею не, Нетерпеливая Загрузка выполнит один дополнительный запрос на тег по почте.

Протестированный с этим кодом:

var options = new DataLoadOptions();
options.LoadWith<Post>(p => p.PostTags);
options.LoadWith<PostTag>(pt => pt.Tag);
using (var db = new BlogDataContext())
{
    db.LoadOptions = options;
    return (from p in db.Posts
            where p.Status != PostStatus.Closed
            orderby p.PublishDateGmt descending
            select p);
}

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

Спасибо

0
ответ дан 17 December 2019 в 07:10
поделиться

Извините. Решение, которое Вы даете работам, но я узнал, что оно повреждается при нумерации страниц со Взятием (N). Полный метод, который я использую, следующий:

public IList<Post> GetPosts(int page, int records)
{
    var options = new DataLoadOptions();
    options.LoadWith<Post>(p => p.PostTags);
    options.LoadWith<PostTag>(pt => pt.Tag);
    using (var db = new BlogDataContext())
    {
        db.LoadOptions = options;
        return (from p in db.Posts
                where p.Status != PostStatus.Closed
                orderby p.PublishDateGmt descending
                select p)
                .Skip(page * records)
                //.Take(records)
                .ToList();
    }
}

Со Взятием () метод прокомментировал, что генерирует запрос, подобный к тому, что Вы отправили, но если я добавляю Взятие () снова, он генерирует 1 + N x M запросы.

Так, я предполагаю, что мой вопрос теперь: существует ли замена к Взятию () метод для нумерации страниц записей?

Спасибо

1
ответ дан 17 December 2019 в 07:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: