在方法中使用表达式<Func<T、布尔>>谓词时"The type 'T' must be a reference type"错误



我正在尝试更改一个方法,使其接受Expression<Func<T, Boolean>> predicate参数。但当我这样做的时候,它会给我一个错误。

这是老方法:

async static Task Delete() {
var F = await cosmosManager.GetDocumentItemsAsync<LogF>(
x => x.Activity == "F");
await cosmosManager.DeleteDocumentItemAsync(F[0].Id);
}

这是一种新方法:

await Delete<LogF>(x => x.Activity == "F");
async static Task Delete<T>(Expression<Func<T, Boolean>> predicate) {
var F = await cosmosManager.GetDocumentItemsAsync<T>(predicate);
await cosmosManager.DeleteDocumentItemAsync(F[0].Id);
}

但这不起作用,我在这里得到了这个错误:cosmosManager.GetDocumentItemsAsync<T>

错误CS0452:类型"T"必须是引用类型,才能将其用作泛型类型或方法中的参数"T"CosmosManager。GetDocumentItemsSync(Expression>('

以下是GetDocumentItemsSync:的代码

public async Task<List<T>> GetDocumentItemsAsync<T>(Expression<Func<T, Boolean>> predicate) where T : class
{
List<T> Items = new List<T>();
collectionLink = UriFactory.CreateDocumentCollectionUri(databaseId, collectionId);
var query = client.CreateDocumentQuery<T>(collectionLink)
.Where(predicate)
.AsDocumentQuery();
while (query.HasMoreResults)
{
var retrivedData1 = await query.ExecuteNextAsync<T>();
Items.AddRange(retrivedData1);
}
return Items;
}

有人能给我一个建议,告诉我如何使用参数来完成方法的"where"部分,以及如何使用参数调用它:

x => x.Activity == "F"

此外,这只适用于检索到的第一条记录[0]。我如何更改它以删除所有记录?

只需对您的类型参数应用与GetDocumentItemsAsync<T>:中的相同的约束

async static Task Delete<T>(Expression<Func<T, Boolean>> predicate) where T : class
{
// Implementation as before
}

这将确保Delete方法中的T适用于GetDocumentItemsAsync中的T

然后您会遇到一个问题,即属性IdT中是未知的。您有指定该属性的基类或接口吗?如果是,请将其添加到约束中。

此外,这只适用于检索到的第一条记录[0]。我如何更改它以删除所有记录?

可以迭代所有结果,一次删除一个,或者如果Cosmos提供该功能,则使用批量删除。(我看不到任何东西。(

根据应用程序的不同,您可能希望将其并行化,首先对每个项目调用DeleteDocumentItemAsync,然后使用Task.WhenAll等待所有生成的任务完成。

此外,这只适用于检索到的第一条记录[0]。我如何更改它以删除所有记录?

此代码显示为检索集合,但随后仅删除第一项:

var F = await cosmosManager.GetDocumentItemsAsync<T>(predicate);
await cosmosManager.DeleteDocumentItemAsync(F[0].Id);

也许迭代集合是合适的:

var F = await cosmosManager.GetDocumentItemsAsync<T>(predicate);
foreach(var f in F)
await cosmosManager.DeleteDocumentItemAsync(f.Id);

如果这是Azure CosmosDB,那么可能有一种方法可以加快速度,即不将所有记录拖到客户端,只获取Id并逐个删除。我不知道该为您的特定上下文提供什么建议,但我最近不得不实施一些措施来选择性地删除数百万条Azure表存储记录-在Windows Azure表存储中批量删除是一种有用的资源-本质上是利用了一种可以将谓词发送到Azure进行评估的功能。我不知道这是否适用/对你的情况有用

如果只有少数记录需要删除,那么这种简单化的方法可能还可以;Jon提到了WhenAll,它当然会更好地处理更多的项目-考虑(如果你有大量的项目,并且需要保持UI响应(要么是一种排队机制,你可以标记要删除的项目,并通过一些独立的后台进程来处理它们,要么是某种火和遗忘;这里有很多未知。

相关内容

最新更新