我是noSQL的新手,很难理解在调用时实际传递给T的构造函数的数据是什么
GetItemQueryIterator<T>(query).
我发现的大多数示例都使用了“SELECT * FROM mytable”,并且查询中使用的对象模型是myTable数据模式的完整表示,比如包括所有字段。
但是,如果我只想在一个特定的查询中从一个大表中选择几个字段呢?我需要有和许多不同查询一样多的数据模型类型吗?
更准确地说,让我们假设我在类似于下面的容器中有文档。我只对Body嵌套的JSON数据感兴趣,所有其他数据实际上都是在将数据馈送到CosmosDB时由Azure IoTHub推送的:
{
"id": "fa14e6f9-b340-4b86-b7b2-46c58318bce5",
"partitionKey": "VK_THC_Outside",
"Properties": {},
"SystemProperties": {
"iothub-connection-device-id": "VK_THC_Outside",
"iothub-connection-auth-method": "{\"scope\":\"device\",\"type\":\"sas\",\"issuer\":\"iothub\",\"acceptingIpFilterRule\":null}",
"iothub-connection-auth-generation-id": "638151591628992733",
"iothub-content-type": "application/json;charset=utf-8",
"iothub-enqueuedtime": "2023-04-08T19:10:50.932Z",
"iothub-message-source": "Telemetry"
},
"iothub-name": "lackoiothub",
"Body": {
"Temp": "3.30",
"Hum": "91.30",
"SBattery": "3532.00",
"GBattery": "4466",
"RSSI": "-48",
"Version": "4",
"TimeStamp": "2023-04-08T19:10:37Z"
}
},
现在我不想建模或查询整个文档,只想使用这样的查询对其中的一部分进行建模或查询:
var query = new QueryDefinition(
"SELECT i.Body.Temp, i.Body.Hum, i.Body.SBattery, i.Body.GBattery, i.Body.TimeStamp " +
"FROM iothub i " +
"WHERE i.partitionKey = \"VK_THC_Outside\" and i.Body.TimeStamp >= @minDate " +
"ORDER BY i.Body.TimeStamp desc"
).WithParameter("@minDate", DateTime.Today);
我假设我会将字段返回为Temp,Hum,SBattery,GBattery和TimeStamp,因此我创建了一个模型对象:
public class SensorData
{
public string temp { get; set; } = "0";
public string hum { get; set; } = "0";
public string sbatt { get; set; } = "0";
public string gbatt { get; set; } = "0";
public DateTime time { get; set; }
public SensorData(string temp, string hum, string sbatt, string gbatt, string time)
{
Debug.WriteLine($"Sensordata.ctor() : temp: {temp} hum: {hum} sbatt: {sbatt} gbatt: {gbatt} time: {time}");
try
{
this.temp = temp;
this.hum = hum;
this.sbatt = sbatt;
this.gbatt = gbatt;
this.time = DateTime.Parse(time);
}
catch (Exception ex)
{
Debug.WriteLine($"Sensordata.ctor() : Exception : {ex.GetType().Name} {ex.Message}");
this.time = DateTime.Now;
}
}
}
把所有这些放在一起,我有下面的代码:
var query = new QueryDefinition(
"SELECT i.Body.Temp, i.Body.Hum, i.Body.SBattery, i.Body.GBattery, i.Body.TimeStamp " +
"FROM iothub i " +
"WHERE i.partitionKey = \"VK_THC_Outside\" and i.Body.TimeStamp >= @minDate " +
"ORDER BY i.Body.TimeStamp desc"
).WithParameter("@minDate", DateTime.Today);
using FeedIterator<SensorData> feed = container.GetItemQueryIterator<SensorData>(query);
while (feed.HasMoreResults)
{
var sData = await feed.ReadNextAsync();
sData.ForEach(d => _sensorsData.Add(d));
}
结果这不起作用,我没有得到或奇怪的数据传递到SensorData构造函数。感谢调试消息,我可以看到数据没有按预期传递。没有数据传递给SensorData的构造函数参数sbatt,gbatt和time:
Sensordata.ctor() : Exception : ArgumentNullException Value cannot be null. (Parameter 's')
Sensordata.ctor() : temp: 3.50 hum: 91.30 sbatt: gbatt: time:
Exception thrown: 'System.ArgumentNullException' in System.Private.CoreLib.dll
Sensordata.ctor() : Exception : ArgumentNullException Value cannot be null. (Parameter 's')
Sensordata.ctor() : temp: 3.50 hum: 91.20 sbatt: gbatt: time:
Exception thrown: 'System.ArgumentNullException' in System.Private.CoreLib.dll
Sensordata.ctor() : Exception : ArgumentNullException Value cannot be null. (Parameter 's')
Sensordata.ctor() : temp: 3.60 hum: 91.20 sbatt: gbatt: time:
Exception thrown: 'System.ArgumentNullException' in System.Private.CoreLib.dll
Sensordata.ctor() : Exception : ArgumentNullException Value cannot be null. (Parameter 's')
Sensordata.ctor() : temp: 3.60 hum: 91.10 sbatt: gbatt: time:
Exception thrown: 'System.ArgumentNullException' in System.Private.CoreLib.dll
Sensordata.ctor() : Exception : ArgumentNullException Value cannot be null. (Parameter 's')
因此,我找到了另一种方法,首先避免反序列化,并检查查询实际返回的是什么数据。为此,我用GetItemQueryStreamIterator替换了通用的GetItemQueryIterator,并使用下面的代码处理相同的查询:
using FeedIterator feed = container.GetItemQueryStreamIterator(query);
while (feed.HasMoreResults)
{
var response = await feed.ReadNextAsync();
using (StreamReader sr = new StreamReader(response.Content))
using (JsonTextReader jtr = new JsonTextReader(sr))
{
JObject result = JObject.Load(jtr);
}
在上面的循环中检查变量“result”的值,我现在可以看到实际上查询结果与预期的一样:
所以谁能给我指个方向为什么
container.GetItemQueryIterator<SensorData>(query)
没有按预期工作吗
1条答案
按热度按时间wkyowqbh1#
您需要荣誉属性的大写或使用装饰器来分配哪个Json属性与哪个类属性匹配。
第一个是最简单的一个:
也可以使用
JObject
:并使用
JObject
访问器(如item["Hum"]
)获取Hum
属性值。