我正在使用RavenDB 3开发ASP.NET MVC应用程序。我没有很多关于乌鸦的经验。
通常,在执行查询以显示数据时,页面上会返回前128个项目。通过使用分页查询,在"无限滚动" -manner中添加更多记录。
但是,我现在要求将项目加载到'组中。
假设以下课程:
public class Item {
public string Id { get; set; }
public int Group { get; set; }
public string text { get; set; }
}
假设数据库包含40个具有组=' 1'的项目,40个项目具有组=' 2'和50个具有组的项目=' 3'。
共有130件商品。这意味着最后一个小组'取得的不完整。它将缺少2个项目。
我想要一个能够意识到这一点的机制,这样它至少可以获取128并且会获取额外的'如果最后一组没有完全包括在内。
之后,当我获取下一页时,我希望它从下一组开始。
如果没有“制作”,我有什么方法可以完成这项工作。通过多次通话我自己一个页面?
编辑:我不能假设这些组的大小完全相同,但我可以假设大小将是' simular'
此外,我无法更改设计以将所有项目存储在单个“组”对象中。
答案 0 :(得分:0)
好的,基本上你需要做的是计算前几页中的结果数和当前页面中的结果数。下面是一个快速示例应用程序,可以让您了解如何执行此操作。需要注意的是,如果当前组范围的结果数超过MaxNumberOfRequestsPerSession
而不是错误,那么您可能需要在那里进行一些处理。
请注意运行此示例: 如果您使用的是最新版本的RavenDB,请确保您的平台在visual studio中设置为x64。否则,此示例将抛出有关Voron在32位模式下不稳定的错误。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Raven.Client;
using Raven.Client.Embedded;
using Raven.Client.Listeners;
namespace ConsoleApplication
{
internal class Program
{
private static void Main(string[] args)
{
using (var gdm = new GroupDataManager())
{
Console.WriteLine("Started Seeding");
gdm.Seed().Wait();
Console.WriteLine("Finished Seeding");
Console.WriteLine("===============================================================");
Console.WriteLine("Get First Page");
Console.WriteLine("===============================================================");
var firstPage = gdm.GetPagedGroupResults(1, 3).Result;
foreach (var item in firstPage)
{
Console.WriteLine(item.Text);
}
Console.WriteLine("===============================================================");
Console.WriteLine("Get Second Page");
Console.WriteLine("===============================================================");
var secondPage = gdm.GetPagedGroupResults(2, 3).Result;
foreach (var item in secondPage)
{
Console.WriteLine(item.Text);
}
}
Console.ReadLine();
}
}
public class GroupDataManager : IDisposable
{
private readonly IDocumentStore _documentStore = new EmbeddedRavenDatabase().Store;
public void Dispose()
{
_documentStore.Dispose();
}
public async Task Seed()
{
var rnd = new Random();
using (var session = _documentStore.OpenAsyncSession())
{
for (var groupNumber = 1; groupNumber < 15; groupNumber++)
{
for (var i = 0; i < rnd.Next(5, 25); i++)
{
var item = new Item
{
Group = groupNumber,
Text = string.Format("Group: {0} Item:{1}", groupNumber, i)
};
await session.StoreAsync(item);
}
}
await session.SaveChangesAsync();
}
}
public async Task<IList<Item>> GetPagedGroupResults(int page, int numberOfGroupsPerPage)
{
var startingGroup = ((page - 1) * numberOfGroupsPerPage) + 1;
using (var session = _documentStore.OpenAsyncSession())
{
// Calculate the number of items that were contained in the previous groups
var numberToSkip = await session.Query<Item>().CountAsync(item => item.Group < startingGroup);
var endGroup = startingGroup + numberOfGroupsPerPage;
// Calculate the number of items that are in the current range of groups
var numberToTake = await session.Query<Item>().CountAsync(item => item.Group >= startingGroup && item.Group < endGroup);
var results = await session.Query<Item>().Skip(numberToSkip).Take(numberToTake).ToListAsync();
return results;
}
}
}
public class Item
{
public string Id { get; set; }
public int Group { get; set; }
public string Text { get; set; }
}
/// <summary>
/// For Testing Only. Prevents stale queries
/// </summary>
public class NoStaleQueriesAllowed : IDocumentQueryListener
{
public void BeforeQueryExecuted(IDocumentQueryCustomization queryCustomization)
{
queryCustomization.WaitForNonStaleResults();
}
}
public class EmbeddedRavenDatabase
{
private static bool _configured = false;
private static readonly Lazy<IDocumentStore> _lazyDocStore = new Lazy<IDocumentStore>(() =>
{
var docStore = new EmbeddableDocumentStore
{
RunInMemory = true
};
docStore.RegisterListener(new NoStaleQueriesAllowed());
docStore.Initialize();
return docStore;
});
public IDocumentStore Store
{
get { return _lazyDocStore.Value; }
}
}
}