我正在尝试从 CosmosDb 中的
DbSet
中提取所有条目,如下所示:
var list = context.MarketplaceTransactions.ToList();
此操作失败:
信息:2024年8月23日12:44:05.527 CosmosEventId.ExecutingSqlQuery [30100](Microsoft.EntityFrameworkCore.Database.Command)
对分区“(null)”中的容器“StrangeCloudDbContext”执行 SQL 查询[参数=[]]
选择c
从根 c
WHERE (c["Discriminator"] = "MarketplaceTransaction")
信息:2024年8月23日12:44:07.788 CosmosEventId.ExecutedReadNext [30102](Microsoft.EntityFrameworkCore.Database.Command)
执行 ReadNext (2088.0046 ms, 39.43 RU) ActivityId='cdfdac63-7605-4746-a90d-9669cf864d0e',
容器='StrangeCloudDbContext',分区='(空)',参数=[]
选择c
从根 c
WHERE (c["Discriminator"] = "MarketplaceTransaction")
失败:8/23/2024 12:44:07.802 CoreEventId.QueryIterationFailed[10100] (Microsoft.EntityFrameworkCore.Query)迭代上下文类型“StrangeCloud.Api.Data.StrangeCloudDbContext”的查询结果时发生异常。
System.InvalidOperationException:可为 Null 的对象必须有一个值。
在 lambda_method14(闭包,QueryContext,JObject)
在 Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosShapedQueryCompilingExpressionVisitor.QueryingEnumerable`1.Enumerator.MoveNext()
我已打开详细的错误报告和敏感日志记录。
大概数据库中的条目之一对于不为空的属性有一个空条目(也许?)。但是,数据库中有数百万个条目和数十个属性,并且该错误告诉我属性或条目都不是问题所在。
如何找到并解决问题?
您可以使用 AsEnumerable() 然后枚举结果,而不是使用尝试一次具体化所有实体的 ToList()。这样,您可以捕获每个有问题的实体的异常:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
async Task ProcessMarketplaceTransactions(StrangeCloudDbContext context)
{
var problematicEntities = new List<(int index, Exception exception)>();
var validEntities = new List<MarketplaceTransaction>();
int totalProcessed = 0;
try
{
// First, attempt to execute the query without materializing entities
var query = context.MarketplaceTransactions.AsNoTracking();
// Use a small Take() to test if the query executes at all
await query.Take(1).ToListAsync();
// If we get here, the query itself is valid. Now let's process entities.
await foreach (var entity in query.AsAsyncEnumerable())
{
try
{
// Attempt to access all properties to force full materialization
var temp = new
{
entity.Id,
// List all other properties here
};
validEntities.Add(entity);
}
catch (Exception ex)
{
problematicEntities.Add((totalProcessed, ex));
}
totalProcessed++;
// Optional: Add a break condition if you want to limit processing
// if (totalProcessed >= 1000000) break;
}
}
catch (Exception ex)
{
Console.WriteLine($"Query execution failed: {ex.Message}");
return; // Exit if we can't even start the query
}
Console.WriteLine($"Total entities processed: {totalProcessed}");
Console.WriteLine($"Valid entities: {validEntities.Count}");
Console.WriteLine($"Problematic entities: {problematicEntities.Count}");
foreach (var (index, exception) in problematicEntities)
{
Console.WriteLine($"Error at index {index}: {exception.Message}");
}
}
// Usage
await ProcessMarketplaceTransactions(context);