我正在尝试仅在SELECT查询中获取此人的成员资格信息,即ID,姓名和委员会成员资格。这是我的目标:
{
"id": 123,
"name": "John Smith",
"memberships": [
{
"id": 789,
"name": "U.S. Congress",
"yearElected": 2012,
"state": "California",
"committees": [
{
"id": 444,
"name": "Appropriations Comittee",
"position": "Member"
},
{
"id": 555,
"name": "Armed Services Comittee",
"position": "Chairman"
},
{
"id": 678,
"name": "Veterans' Affairs Comittee",
"position": "Member"
}
]
}
]
}
在这个例子中,约翰史密斯是美国国会的成员和三个委员会。
我想要的结果应该是这样的。再次,这是“理想的结果”:
{
"id": 789,
"name": "U.S. Congress",
"committees": [
{
"id": 444,
"name": "Appropriations Committee",
"position": "Member"
},
{
"id": 555,
"name": "Armed Services Committee",
"position": "Chairman"
},
{
"id": 678,
"name": "Veterans' Affairs Committee",
"position": "Member"
}
]
}
这是我的SQL查询:
SELECT m.id, m.name,
[
{
"id": c.id,
"name": c.name,
"position": c.position
}
] AS committees
FROM a
JOIN m IN a.memberships
JOIN c IN m.committees
WHERE a.id = "123"
我得到的结果如下,但形状不正确。我获得了3次相同的会员资格。这就是我得到的不是理想的结果:
[
{
"id": 789,
"name": "U.S. Congress",
"committees":[
{
"id": 444,
"name": "Appropriations Committee",
"position": "Member"
}
]
},
{
"id": 789,
"name": "U.S. Congress",
"committees":[
{
"id": 555,
"name": "Armed Services Committee",
"position": "Chairman"
}
]
},
{
"id": 789,
"name": "U.S. Congress",
"committees":[
{
"id": 678,
"name": "Veterans' Affairs Committee",
"position": "Member"
}
]
}
]
正如你在这里看到的那样,“美国国会”成员资格重复了3次。
以下SQL查询在Azure Query Explorer中获取了我想要的内容,但当我在代码中将其作为查询传递时 - 使用DocumentDb SDK - 我没有得到委员会的任何详细信息。我只是得到委员会ID,姓名和职位的空白结果。但是,我会得到会员资料,即“美国国会”等。这就是SQL查询:
SELECT m.id, m.name, m.committees AS committees
FROM c
JOIN m IN c.memberhips
WHERE c.id = 123
我包含了进行DocumentDb调用的代码。我将这些代码包含在我们的内部评论中,以帮助澄清其目的:
首先我们在需要从DocumentDb中读取内容时调用ReadQuery函数:
public async Task<IEnumerable<T>> ReadQuery<T>(string collectionId, string sql, Dictionary<string, object> parameterNameValueCollection)
{
// Prepare collection self link
var collectionLink = UriFactory.CreateDocumentCollectionUri(_dbName, collectionId);
// Prepare query
var query = getQuery(sql, parameterNameValueCollection);
// Creates the query and returns IQueryable object that will be executed by the calling function
var result = _client.CreateDocumentQuery<T>(collectionLink, query, null);
return await result.QueryAsync();
}
以下函数准备查询 - 使用任何参数:
protected SqlQuerySpec getQuery(string sql, Dictionary<string, object> parameterNameValueCollection)
{
// Declare query object
SqlQuerySpec query = new SqlQuerySpec();
// Set query text
query.QueryText = sql;
// Convert parameters received in a collection to DocumentDb paramters
if (parameterNameValueCollection != null && parameterNameValueCollection.Count > 0)
{
// Go through each item in the parameters collection and process it
foreach (var item in parameterNameValueCollection)
{
query.Parameters.Add(new SqlParameter($"@{item.Key}", item.Value));
}
}
return query;
}
此函数对DocumentDb进行异步调用:
public async static Task<IEnumerable<T>> QueryAsync<T>(this IQueryable<T> query)
{
var docQuery = query.AsDocumentQuery();
// Batches gives us the ability to read data in chunks in an asyc fashion.
// If we use the ToList<T>() LINQ method to read ALL the data, the call will synchronous which is why we prefer the batches approach.
var batches = new List<IEnumerable<T>>();
do
{
// Actual call is made to the backend DocumentDb database
var batch = await docQuery.ExecuteNextAsync<T>();
batches.Add(batch);
}
while (docQuery.HasMoreResults);
// Because batches are collections of collections, we use the following line to merge all into a single collection.
var docs = batches.SelectMany(b => b);
// Return data
return docs;
}
答案 0 :(得分:0)
我只是编写一个演示来测试你的查询,我可以得到预期的结果,检查下面的快照。所以我认为该查询是正确的,您已经提到过,当您在我的代码中拨打电话时,您似乎无法获取任何数据,您介意分享您的代码吗?也许你的代码中有一些错误。无论如何,这是我的测试仅供您参考,希望它有所帮助。
使用的查询:
SELECT m.id AS membershipId, m.name AS membershipNameName, m.committees AS committees
FROM c
JOIN m IN c.memberships
WHERE c.id = "123"
此处的代码非常简单,sp_db.innerText表示我用于在测试页面中显示结果的范围:
var docs = client.CreateDocumentQuery("dbs/" + databaseId + "/colls/" + collectionId,
"SELECT m.id AS membershipId, m.name AS membershipName, m.committees AS committees " +
"FROM c " +
"JOIN m IN c.memberships " +
"WHERE c.id = \"123\"");
foreach (var doc in docs)
{
sp_db.InnerText += doc;
}
我想在 client.CreateDocumentQuery()中指定的查询中可能存在一些拼写错误,这会导致结果为无,为我们提供代码更好,然后我们可以帮忙检查一下。
<强> 更新 强>
刚试过你的代码,我仍然能得到预期的结果。我发现的一件事是,当我指定where子句时,如&#34;其中c.id = \&#34; 123 \&#34;&#34; ,它会得到结果:
但是,如果你没有进行逃生,只需使用&#34;其中c.id = 123&#34;,这次你什么也得不到。我认为这可能是一个原因。您可以验证是否遇到过这种情况
答案 1 :(得分:0)
刚刚更新了我原来的帖子。问题中提供的所有代码都是正确且有效的。我遇到了问题,因为我在SELECT查询中使用了别名,因此一些属性没有绑定到我的域对象。
问题中提供的代码是正确的。