我正在尝试将 Azure Cosmos DB 用于 Apache Gremlin。但是,当我第一次尝试向数据库添加新顶点时,它会抛出错误。我确认我已经设置了所需的属性,并且它们不能为空。
这是完整的错误:
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
ExRam.Gremlinq.Core.Execution.GremlinQueryExecutionException: Executing query 827bd7f2-3ae7-4b70-93ae-ef0ef18a2951 failed.
---> Gremlin.Net.Driver.Exceptions.ResponseException: ServerEvaluationError:
ActivityId : 7be8d7fe-6e53-4970-9418-84c6835c4b0a
ExceptionType : GraphRuntimeException
ExceptionMessage :
Gremlin Query Execution Error: Cannot add a vertex where the partition key property has value 'null'.
GremlinRequestId : 827bd7f2-3ae7-4b70-93ae-ef0ef18a2951
Context : graphcompute
Scope : graphcomp-execquery
GraphInterOpStatusCode : GraphRuntimeError
HResult : 0x80131500
--- End of inner exception stack trace ---
at ExRam.Gremlinq.Providers.Core.GremlinqClientFactory.GremlinQueryExecutorImpl.<Execute>g__Core|3_0[T](GremlinQueryExecutorImpl this, GremlinQueryExecutionContext context, CancellationToken ct)+MoveNext() in /_/src/Providers.Core/Factory/GremlinqClientFactory.cs:line 222
at ExRam.Gremlinq.Providers.Core.GremlinqClientFactory.GremlinQueryExecutorImpl.<Execute>g__Core|3_0[T](GremlinQueryExecutorImpl this, GremlinQueryExecutionContext context, CancellationToken ct)+MoveNext() in /_/src/Providers.Core/Factory/GremlinqClientFactory.cs:line 217
at ExRam.Gremlinq.Providers.Core.GremlinqClientFactory.GremlinQueryExecutorImpl.<Execute>g__Core|3_0[T](GremlinQueryExecutorImpl this, GremlinQueryExecutionContext context, CancellationToken ct)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()
at ExRam.Gremlinq.Core.AsyncEnumerable.FirstAsync[TSource](IAsyncEnumerable`1 source, CancellationToken ct) in /_/src/Core/Extensions/AsyncEnumerable.cs:line 32
at ExRam.Gremlinq.Core.AsyncEnumerable.FirstAsync[TSource](IAsyncEnumerable`1 source, CancellationToken ct) in /_/src/Core/Extensions/AsyncEnumerable.cs:line 32
at AzheirAPI.Controllers.AccountsController.Register(Dictionary`2 request) in D:\GodotProjects\azheir\AzheirWebsite\AzheirAPI\Controllers\AccountsController.cs:line 267
at lambda_method19(Closure, Object)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
info: Microsoft.Azure.SignalR.ServiceConnection[12]
这是 Program.cs 类,我在其中告诉查询源如何找到我的 PartitionKey:
var hostname = builder.Configuration["Azure:CosmosDB:Gremlin:Hostname"]!;
var port = builder.Configuration["Azure:CosmosDB:Gremlin:Port"]!;
var authentication = builder.Configuration["Azure:CosmosDB:Gremlin:AuthKey"]!;
var database = builder.Configuration["Azure:CosmosDB:Gremlin:Database"]!;
var graph = builder.Configuration["Azure:CosmosDB:Gremlin:Graph"]!;
var fullUri = $"wss://{hostname}:{port}/";
IGremlinQuerySource gremlinQuerySource = GremlinQuerySource.g
.UseCosmosDb<Vertex, Edge>(configurator => configurator
.At(new Uri(fullUri))
.OnDatabase(database)
.OnGraph(graph)
.WithPartitionKey(x => x.PartitionKey!)
.AuthenticateBy(authentication)
.UseNewtonsoftJson());
builder.Services.AddSingleton(gremlinQuerySource);
这是我定义 Vertex 类及其继承的方式:
public class Vertex
{
public string? Id { get; set; }
public string? PartitionKey { get; set; } = "/AzheirGraph";
}
public class Edge
{
public string? Id { get; set; }
public string? PartitionKey { get; set; } = "/AzheirGraph";
}
public class Account : Vertex
{
public string Avatar { get; set; } = string.Empty;
public required string Email { get; set; } = string.Empty;
public required string Password { get; set; } = string.Empty;
public string FullName { get; set; } = string.Empty;
public string PhoneNumber { get; set; } = string.Empty;
public DateTime DateOfBirth { get; set; } = DateTime.MaxValue;
public DateTime CreatedDate { get; set; } = DateTime.UtcNow;
public Gender Gender { get; set; } = Gender.Unknown;
public int Points { get; set; } = 0;
public bool IsConfirmed { get; set; } = false;
public bool NewsletterSubscription { get; set; } = false;
}
我的 csproj 文件
<PackageReference Include="ExRam.Gremlinq.Core" Version="12.10.0" />
<PackageReference Include="ExRam.Gremlinq.Core.AspNet" Version="12.10.0" />
<PackageReference Include="ExRam.Gremlinq.Providers.Core" Version="12.10.0" />
<PackageReference Include="ExRam.Gremlinq.Providers.CosmosDb" Version="12.10.0" />
<PackageReference Include="ExRam.Gremlinq.Providers.CosmosDb.AspNet" Version="12.10.0" />
<PackageReference Include="ExRam.Gremlinq.Providers.GremlinServer" Version="12.10.0" />
<PackageReference Include="ExRam.Gremlinq.Providers.GremlinServer.AspNet" Version="12.10.0" />
<PackageReference Include="ExRam.Gremlinq.Support.NewtonsoftJson" Version="12.10.0" />
<PackageReference Include="ExRam.Gremlinq.Support.NewtonsoftJson.AspNet" Version="12.10.0" />
<PackageReference Include="FlakeId" Version="1.2.0" />
<PackageReference Include="Gremlin.Net" Version="3.7.2" />
以下是它的使用方法:
AzheirAPI.Elements.Account newAccount = new()
{
Id = Guid.NewGuid().ToString(),
Email = requestEmail,
Password = Argon2.Hash(requestPassword),
};
// This line causing: Gremlin Query Execution Error: Cannot add a vertex where the partition key property has value 'null'.
Elements.Account createdAccount = await gremlinQuerySource.AddV(newAccount).FirstAsync();
Console.WriteLine($"createdAccount: {createdAccount}");
我尝试删除 Azure 上的图表,然后使用设置为“/AzheirGraph”的 PartitionKey 重新创建它。我还尝试从该键中删除“/”,但这也不起作用。请指出我可能做错了什么。这是我第一次与 Cosmos DB 和 Gremlin 交互,所以我不知道我可能做错了什么。