C# DocumentDb无法处理列名中的连字符(-)

C# DocumentDb无法处理列名中的连字符(-),c#,azure-cosmosdb,C#,Azure Cosmosdb,我正在将以下XML保存到DocumentDB: <DocumentDbTest_Countries> <country>C25103657983</country> <language>C25103657983</language> <countryCode>383388823</countryCode> <version>2015-08-25T08:36:59:982.3552

我正在将以下XML保存到DocumentDB:

<DocumentDbTest_Countries> 
  <country>C25103657983</country> 
  <language>C25103657983</language> 
  <countryCode>383388823</countryCode>
  <version>2015-08-25T08:36:59:982.3552</version>
  <integrity>
     <hash-algorithm>sha1</hash-algorithm>
     <hash /> 
  </integrity>
  <context-info> 
     <created-by>unittestuser</created-by> 
     <created-on>2015/08/25 08:36:59</created-on> 
     <created-time-zone>UTC</created-time-zone> 
     <modified-by>unittestuser</modified-by>
     <modified-on>2015/08/25 08:36:59</modified-on> 
     <modified-time-zone>UTC</modified-time-zone>
  </context-info>
</DocumentDbTest_Countries>
正如您所看到的,列名确实是用连字符(-)保存在DocumentDB中的(显然没有任何类型的错误/异常/警告),但是当我尝试在查询资源管理器中进行查找时,它失败了。似乎没有办法在连字符的列名上搜索。这是真的吗?或者,我错过了什么?有人能给我指一下某个地方关于这个限制的文档吗

您还可以使用带引号的属性运算符[]访问属性。例如,选择c.grade和选择c[“grade”]是等效的。当需要转义包含空格、特殊字符或恰好与SQL关键字或保留字共享相同名称的属性时,此语法非常有用

-
是这些特殊字符之一,因此要访问包含
-
的属性,您需要使用带引号的属性运算符。有文件记载:)

当然,惯用的方法是使用驼峰式大小写而不是连字符,但是如果您不想更改结构,则需要使用带引号的属性

例如,使用您的测试数据,此查询工作:

SELECT c["country-code"] FROM root.DocumentDbTest_Countries c
编辑:

查询的语法有点混乱,这就是导致大多数问题的原因。与你的想法相反

select * from DocumentDbTest_Countries
事实上,这并不意味着“获取
DocumentDbTest\u国家的所有数据”。相反,它似乎意味着“获取当前集合中的所有数据,并将其别名为
DocumentDbTest\u Countries
”。当您查看返回的数据时,这一点很明显-您希望它只返回
DocumentDbTest_Countries
中的字段,但实际上它返回所有值,包括
id
(它不是
DocumentDbTest_Countries
的一部分-应该在前面就很明显了:d)

我不明白它为什么会这样设计(即使使用
DocumentDbTest\u Countries c
来明确指定别名,也不会选择
DocumentDbTest\u Countries
),但修复方法是实际使用集合名称启动标识符<代码>根目录
只是引用“此集合”的一种方式,因此

返回您期望从原始查询得到的结果。除非您弄清楚原始查询的行为方式,否则我坚持每次都显式地使用
root
(或集合名称)作为根。在我看来,使用
from which
总是会返回当前集合,除非您有一个名为
which
的集合-如果您问我,这是一个奇怪的设计决策。这意味着,除非您有一个名为
lotsofun
的集合,否则以下操作与使用
root
的操作相同:

select * from lotsOfFun.DocumentDbTest_Countries

可能是因为顶级对象没有命名,所以他们决定不管名称如何都可以,但这只是一个想法。

对于使用某些字符(空格、“@”、“-”等)或与SQL关键字冲突的字段名,必须使用带引号的属性访问器语法。因此,与其写:

SELECT * FROM c WHERE c.context-info.created-by = "unittestuser"
写:

SELECT * FROM c WHERE c["context-info"]["created-by"] = "unittestuser"

诀窍是使用CollectionName.DocumentName而不仅仅是DocumentName,就像这样(感谢@Laan为我指明了方向)::


但是我仍然错过了返回文档数据中的Document.Id和Document.SelfLink数据。

您是否尝试在查询中用下划线替换连字符?@Luca,我当然可以,我也可以删除连字符。但这已经超出了重点。此数据是存储在Sql Server(Xml)中的现有数据,也可以按原样进行查询。因此,读者也期望数据中包含一个hypehen(-)。现在我已经更改了阅读器代码,也必须更新,除非非常需要,否则我不想这样做。:)另外,我希望MSDN提供一些关于此限制/限制的文档,然后考虑解决方法。Deb,我下面的回答是否为您提供了技巧?如果是的话,你能接受我的回答吗?谢谢你的回复。我已经尝试过c[国家代码]的方式,但也不起作用。您正在谈论的有文档记录的引用属性运算符也没有说明任何内容@黛布:这些引语很重要。它必须是
c[“国家代码”]
,而不是
c[国家代码]
。当然,后者可以与MS SQL一起使用,但这不是MS SQL。我也尝试了c[“国家代码”]——但这也不起作用。您是否有c[“国家代码”]的工作示例可能???
country code
可能是一个不好的示例,因为您的示例将
country code
作为字段名。为此,只需使用
c.countryCode
。对于由创建的
,请使用由“]
创建的
c[”。更正:对于由
创建的
上下文信息,请使用由“]
创建的
c[“上下文信息”]。@Larry,感谢您的回复。我已经试过了,但不起作用。为了证明这一点,请检查这个黛布,我想我看到了你的问题。在查询3中,您省略了查询的DocumentDbTest_Countries部分。这一行应该是:
string query3=“SELECT*FROM DocumentDbTest\u Countries c其中c[\“DocumentDbTest\u Countries\”][\“@country\”]=\“C260
…当然,您会错过它,
id
不是
DocumentDbTest\u Countries
的一部分,它是其父项的一部分(在本例中是
TestProject
项)。显然,您的对象是真实集合项的有效负载,并且真实集合项具有ID之类的元数据。如果您需要ID,只需从TestProject中获取
,@Luaan我不理解,也不同意:)事实上,此DocumentDbTest\u Countries是集合的一部分,不是文档中的文档,因此它有自己的Id和自链接,就像该集合中其他保存的文档一样-因此我希望Id和自链接,当我从D中选择*的时候,我得到了很好的结果
SELECT * FROM c WHERE c.context-info.created-by = "unittestuser"
SELECT * FROM c WHERE c["context-info"]["created-by"] = "unittestuser"
SELECT * FROM TestProject.DocumentDbTest_Countries c where c["@country"] = "C26092630539"