我想知道是否有任何方法可以使用或不使用他们的Linq提供程序在C#中对DocumentDB实现分页?
场景:我有一个支持分页的API,用户在页面中发送他们想要查看的pageSize,例如:
public virtual async Task<HttpResponseMessage> Get(int? page = DefaultPage, int? pageSize = DefaultPageSize)
然后,我使用这些参数使用以下代码对数据访问层中的数据进行分页:
return query.Skip((pageNumber - 1) * pageSize).Take(pageSize);
"那么问题是什么?",你可能会问.嗯,这种方法和代码在使用EF和SQL时非常有效.问题是我想开始使用DocumentDB,但他们的Linq实现不支持Skip.我见过的唯一例子包括使用TOP关键字或延续令牌,这与我不适合允许用户发送pageNumber和pageSize.
是否有任何实现仍然允许我的用户提供pageNumber并pageSize在请求中?
在Microsoft示例中,我看到了两种方法来检查DocumentDb对象是否存在,如Database,DocumentCollection,Document等:
首先是创建一个查询:
Database db = client.CreateDatabaseQuery().Where(x => x.Id == DatabaseId).AsEnumerable().FirstOrDefault();
if (db == null)
{
await client.CreateDatabaseAsync(new Database { Id = DatabaseId });
}
Run Code Online (Sandbox Code Playgroud)
第二个是使用"try catch"块:
try
{
await this.client.ReadDatabaseAsync(UriFactory.CreateDatabaseUri(databaseName));
}
catch (DocumentClientException de)
{
if (de.StatusCode == HttpStatusCode.NotFound)
{
await this.client.CreateDatabaseAsync(new Database { Id = databaseName });
}
else
{
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
在性能方面执行此过程的正确方法是什么?
我有以下代码。
async function bulkInsert(db, collectionName, documents) {
try {
const cosmosResults = await db.collection(collectionName).insertMany(documents);
console.log(cosmosResults);
return cosmosResults
} catch (e) {
console.log(e)
}
}
Run Code Online (Sandbox Code Playgroud)
如果我使用大量文档来运行它,我会得到(并非意外)
{ MongoError: Message: {"Errors":["Request rate is large"]}
ActivityId: b3c83c38-0000-0000-0000-000000000000,
Request URI: /apps/DocDbApp/services/DocDbServer24/partitions/a4cb4964-38c8-11e6-8106-8cdcd42c33be/replicas/1p/,
RequestStats: , SDK: Microsoft.Azure.Documents.Common/1.19.102.5
at G:\Node-8\NodeExample\node_modules\oracle-movie-ticket-demo\node_modules\mongodb-core\lib\connection\pool.js:596:61
at authenticateStragglers (G:\Node-8\NodeExample\node_modules\oracle-movie-ticket-demo\node_modules\mongodb-core\lib\connection\pool.js:514:16)
at Connection.messageHandler (G:\Node-8\NodeExample\node_modules\oracle-movie-ticket-demo\node_modules\mongodb-core\lib\connection\pool.js:550:5)
at emitMessageHandler (G:\Node-8\NodeExample\node_modules\oracle-movie-ticket-demo\node_modules\mongodb-core\lib\connection\connection.js:309:10)
at TLSSocket.<anonymous> (G:\Node-8\NodeExample\node_modules\oracle-movie-ticket-demo\node_modules\mongodb-core\lib\connection\connection.js:452:17)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at TLSSocket.Readable.push (_stream_readable.js:208:10)
name: 'MongoError',
message: 'Message: {"Errors":["Request rate is large"]}\r\nActivityId: b3c83c38-0000-0000-0000-000000000000,
Request …Run Code Online (Sandbox Code Playgroud) 我正在使用单元测试来测试DocumentDBRepository课程。我按照这篇文章作为 SQL 查询用例的示例。但它显示错误
消息:System.InvalidCastException:无法将类型“System.Linq.EnumerableQuery”的对象转换为类型“Microsoft.Azure.Documents.Linq.IDocumentQuery”
这是我的DocumentDBRepository课程代码
private IDocumentQuery<T> GetQueryBySQL(string queryStr)
{
var uri = UriFactory.CreateDocumentCollectionUri(_databaseId, _collectionId);
var feedOptions = new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = true };
IQueryable<T> filter = _client.CreateDocumentQuery<T>(uri, queryStr, feedOptions);
IDocumentQuery<T> query = filter.AsDocumentQuery();
return query;
}
public async Task<IEnumerable<T>> RunQueryAsync(string queryString)
{
IDocumentQuery<T> query = GetQueryBySQL(queryString);
List<T> results = new List<T>();
while (query.HasMoreResults)
{
results.AddRange(await query.ExecuteNextAsync<T>());
}
return results;
}
Run Code Online (Sandbox Code Playgroud)
这是我的测试类的代码
public async virtual Task Test_GetEntitiesAsyncBySQL()
{
var id …Run Code Online (Sandbox Code Playgroud) 我正在从 .NET Core 应用程序查询 Cosmos DB 集合。现在我想知道,在如何向查询提供分区键方面是否有任何区别(即:以一种方式与另一种方式相比更好)?
下面region是我的分区键。
A)
var queryString = $"SELECT TOP 100 * FROM c WHERE c.region ='{region}'";
var query = this.container.GetItemQueryIterator<Item>(new QueryDefinition(queryString));
Run Code Online (Sandbox Code Playgroud)
b)
var queryString = "SELECT TOP 100 * FROM c";
var query = this.container.GetItemQueryIterator<Item>(new QueryDefinition(queryString), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey(region) });
Run Code Online (Sandbox Code Playgroud)
至少 RU(请求单位)看起来是相同的,所以 Cosmos DB 可能会在内部优化查询并将 a) 重写为 b),反之亦然?!
Microsoft 提供了两种在 C#/.NET 中使用 Cosmos 数据库的方法。
可以使用 Entity Framework(EF) Core,它在幕后利用 cosmos SDK,并允许您将 EF 与 Cosmos 结合使用。
最后一点可以被视为积极或消极,具体取决于您是否想使用 EF 与 Dapper 或其他什么,但对于我的用例,我更愿意使用 EF,除非有充分的理由不这样做。
我可以找到微软本身没有就应该使用哪个或为什么使用任何声明。(我假设这是一个 .NET Core 项目)
我正在开发一个新项目,有人建议我看看 Cosmos DB 以用于我的数据存储,因为它将成为一个全球 SaaS 应用程序,为潜在的数十万用户提供服务。
由于这是我第一次涉足 NoSQL 数据库,我不可避免地遇到了很多需要学习的东西,但我觉得我已经慢慢掌握了它,并且实际上对此感到非常兴奋。
现在问题来了:我有一个相对简单的数据结构,我似乎无法理解如何实现,而且我几乎已经接受了这样一个事实:它可能只是一个工作负载,而不是“在非关系数据库中确实工作得很好。但正如我所说,我完全是绿色的,所以我来这里是为了进行健全性检查,以防我遗漏了一些明显的东西
我有一个由“用户”对象和“帖子”对象组成的数据结构,我需要根据无界标签数组将它们关联起来,以基本上创建自定义的提要,它们看起来像这样
用户:
{
id: 1,
name: "username",
interests: [
"fishing",
"photography",
"stargazing",
]
}
Run Code Online (Sandbox Code Playgroud)
邮政:
{
id: 1,
title: "My post title",
body: "My post content",
tags: [
"tennis",
"sport",
"photography",
]
}
Run Code Online (Sandbox Code Playgroud)
我想返回所有帖子的列表,这些帖子的标签中有一个或多个给定用户的兴趣,所以基本上是这样的查询:
SELECT DISTINCT VALUE Posts FROM Posts
JOIN tag IN Posts.Tags
WHERE tag IN <<user.interests>>
Run Code Online (Sandbox Code Playgroud)
在 SQL 中,我创建一个用户表和一个帖子表,并根据共享标签/兴趣将它们连接起来,但我一生都无法弄清楚如何对其进行非规范化(如果可能的话)。在我第一次尝试仅使用 2 个对象时,我是否真的遇到了 NoSQL 不可能的流程之一?或者我只是个菜鸟?
database azure data-structures azure-cosmosdb azure-cosmosdb-sqlapi
实体框架有一些关于嵌入实体的很好的文档,但我不知道如何嵌入一个简单的字符串数组IEnumerable<string>。
样板课
public class Post {
public string Id {get;set;}
public string Content {get;set;}
public IEnumerable<string> Tags {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
这应该在 cosmos 中保存为:
{
"id": "xxx",
"content": "long content here",
"tags": ["tag1", "tag2"],
...
}
Run Code Online (Sandbox Code Playgroud)
我知道我必须在OnModelCreating(ModelBuilder modelBuilder)上下文中配置一些东西。但我无法正确设置它。
我尝试过以下选项(以及其他几种ToJsonProperty方法):
modelBuilder.Entity<Post>().OwnsMany(p => p.Tags);modelBuilder.Entity<Post>().OwnsMany<string>(p => p.Tags);最终我希望能够根据这些标签进行查询,非常感谢任何帮助或正确方向的指示!
我也找到了这个答案,但是将数组转换为逗号分隔的字符串会达不到目的(因为这不允许我们查询这些帖子)。
其他人在 Microsoft 论坛上问了大致相同的问题,其中一位 Microsoft 员工表示,在纯 CosmosDB 中,可以在 cosmos 中嵌入字符串数组。
c# entity-framework-core azure-cosmosdb azure-cosmosdb-sqlapi
考虑以下情况,我有一个看起来像这样的文档:
"id": 2
"properties": {
"desired": {
"Property1": 10,
"Property2": 1,
"Property3": 1,
"$metadata": {
...
},
"$version": 53
}
},
Run Code Online (Sandbox Code Playgroud)
我想从文档中获取所有内容,$metadata除了并且$version明显的解决方案是:
SELECT c["Property1"], c["Property2"] .... FROM c where c["id"] = "2"
Run Code Online (Sandbox Code Playgroud)
但是,我的文档可能会动态扩展,因此上述内容不是最佳的。因此,我认为最好排除$metadata和$version。我在 stackoverflow 上查看了不同的“有趣”解决方案,其中一个建议创建一个临时表。
不幸的是,查询需要非常高效,因为我想减少使用的 RU 量。另外,我真的想避免在代码中处理排除。
因此,如何从文档中排除特定的“列”,而不编写过长的查询(可能包括创建临时表)。
据微软称,他们的 Cosmos DB docker 镜像不能在 Apple Mac M1 芯片上运行。然而,我一直相信我可以通过--platform linux/amd64选项运行针对不同架构的图像。这适用于我尝试过的图像,但对于 Cosmos 图像,我遇到了相同的与拱门相关的错误。
./palrun: ERROR: Invalid mapping of address 0x40037dd000 in reserved address space below 0x400000000000. Possible causes:
1) the process (itself, or via a wrapper) starts-up its own running environment sets the stack size limit to unlimited via syscall setrlimit(2);
2) the process (itself, or via a wrapper) adjusts its own execution domain and flag the system its legacy personality via syscall personality(2);
3) sysadmin deliberately sets …Run Code Online (Sandbox Code Playgroud) azure-cosmosdb ×10
azure ×4
c# ×4
c ×1
database ×1
docker ×1
javascript ×1
linq ×1
mongodb ×1
moq ×1
node.js ×1
nosql ×1
pagination ×1
sdk ×1
sql ×1
unit-testing ×1