在单个查询中从CosmosDb获取多种类型的实体

3

我正在尝试使用Sql API从CosmosDb的集合中获取所有实体类型。但是,我只能获取BaseClass实体,而不能获取特定类实体。

以下是我的模型:

public class ActivityBase: { // common properties for all activities... }
public class Running: ActivityBase { // specific properties to Running... }
public class Dancing: ActivityBase { // specific properties to Dancing... }

以下是当前的查询语句:

 var query = Client.CreateDocumentQuery<ActivityBase>(collection.SelfLink, feedOptions)
                .Where(/*some filter which does not exclude entities by ActivityType*/) 
                .AsDocumentQuery();

我最终得到的是一个List<ActivityBase>

我需要的是一个List<ActivityBase>,其中包含特定的实体,如RunningDancing,而不仅仅是基类对象。是否有一种方法可以在查询本身中指定这一点?

2个回答

0

CreateDocumentQuery 中的 T 类型只是告诉 SDK 要在哪里映射检索到的对象,并不是要查询哪些对象,这部分内容应该放在筛选器中。

如果您的筛选器没有将查询缩小到 RunningDancing 类型,那么此查询将仅检索任何类型的对象,然后映射到 ActivityBase。这意味着即使您正在查询正确的类型,也永远无法看到它们,因为映射器会忽略它们。

您可以通过将 T 类型更改为 dynamicDocument 并检查内容来快速检查。


我同意并知道。我的过滤器不会按活动类型排除(已更新问题)。我尝试过使用“dynamic”方法,但是对于每个对象,我都必须尝试并转换为每个活动,这听起来不太好。有没有现成的方法可以做到这一点? - bit
1
没有,使用这个SDK是不行的。您需要每个类型查询一个查询或一些标志来指示这个项目是什么,以便更轻松地进行重新映射。 - Nick Chapsas

0
这是不可能的。如果基类没有这些属性,你怎么能返回ActivityBase并期望它具有Running的特定属性?
你必须返回一个动态对象或创建一个容器对象来返回。
public class ActivitiesResponse {
   public List<Running> RunningActivities { get; set; } = new List<Running>();
   public List<Dancing> DancingActivities { get; set; } = new List<Dancing>();
}

然后使用dynamic查询它

在CosmosDB中,确保将类型添加到两种对象类型中,以便您知道返回的对象是什么:

public class Running {
  public string Type {get; set;} = nameof(Running);
  // other properties
}
public class Dancing {
  public string Type {get; set;} = nameof(Dancing);
  // other properties
}

现在将查询设置为动态,然后基于类型反序列化为适当的对象并返回包含两种类型的 ActivitiesResponse

var iterator = container.GetItemLinqQueryable<dynamic>()
    .Where(p => /* some query */)
    .ToFeedIterator();

var result = new ActivitiesResponse();

while (iterator.HasMoreResults)
{
    var response = await iterator.ReadNextAsync();
    
    foreach(var item in response){ 
        if(item.Type == nameof(Running)){
          var runningActivity = JsonConvert.DeserializeObject<Running>(item.ToString());
          result.RunningActivities.Add(runningActivity);
        }
        else if(item.Type == nameof(Dancing)){
          var dancingActivity = JsonConvert.DeserializeObject<Dancing>(item.ToString());
          result.DancingActivities.Add(dancingActivity);
        }
    }    
}

return result;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接