DocumentDB LINQ查询 - 不支持选择方法

时间:2018-04-18 11:57:53

标签: join lambda azure-cosmosdb

应用程序:

示例文档结构:



{
	"ProfileName": "User Profile 123",
	"Country": "UK",
	"Tags": [{
		"Id": "686e4c9c-f1ab-40ce-8472-cc5d63597263",
		"Name": "Tag 1"
	},
	{
		"Id": "caa2c2a0-cc5b-42e3-9943-dcda776bdc20",
		"Name": "Tag 2"
	}],
	"Topics": [{
		"Id": "baa2c2a0-cc5b-42e3-9943-dcda776bdc20",
		"Name": "Topic A"
	},
	{
		"Id": "aaa2c2a0-cc5b-42e3-9943-dcda776bdc30",
		"Name": "Topic B"
	},
	{
		"Id": "eaa2c2a0-cc5b-42e3-9943-dcda776bdc40",
		"Name": "Topic C"
	}]
}




问题: 我遇到的问题是我执行的任何包含.Select的LINQ查询都会返回一个错误,指出不支持Select方法。

我需要什么? 我希望能够使用LINQ表达式返回所有文档WHERE:

  1. 国家=英国
  2. 标签包含特定的GUID
  3. 主题包含特定的GUID

1 个答案:

答案 0 :(得分:1)

  

我需要什么?我希望能够使用LINQ表达式返回所有文档

在您的情况下,标签和主题是对象数组,如果您使用以下linq代码,它将获得 null

 var q = from d in client.CreateDocumentQuery<Profile>(
                    UriFactory.CreateDocumentCollectionUri("database", "coll"))
                where d.Country == "UK"  && d.Tags.Contains(new Tag
                {
                   Id = "686e4c9c-f1ab-40ce-8472-cc5d63597264"
                }) && d.Topics.Contains(new Topic
                {
                    Id = "baa2c2a0-cc5b-42e3-9943-dcda776bdc22"
                })
                select d;

我还尝试覆盖标记和主题

IEqualityComparer
public class CompareTag: IEqualityComparer<Tag>
    {


        public bool Equals(Tag x, Tag y)
        {
            return x != null && x.Id.Equals(y?.Id);
        }

        public int GetHashCode(Tag obj)
        {
            throw new NotImplementedException();
        }
    }

然后再试一次然后Azure documentDb SDK 包含 不支持

 var q = from d in client.CreateDocumentQuery<Profile>(
                    UriFactory.CreateDocumentCollectionUri("database", "coll"))
                where d.Country == "UK"  && d.Tags.Contains(new Tag
                {
                   Id = "686e4c9c-f1ab-40ce-8472-cc5d63597264"
                },new CompareTag()) && d.Topics.Contains(new Topic
                {
                    Id = "baa2c2a0-cc5b-42e3-9943-dcda776bdc22"
                }, new CompareTopic())
                    select d;

我的解决方法是我们可以直接使用SQL查询。它在我身边正常工作。我们也可以在Azure门户上测试它。

SELECT * FROM root WHERE (ARRAY_CONTAINS(root.Tags, {"Id": "686e4c9c-f1ab-40ce-8472-cc5d63597263"}, true) And ARRAY_CONTAINS(root.Topics, {"Id": "baa2c2a0-cc5b-42e3-9943-dcda776bdc20"}, true) And root.Country = 'UK' )

enter image description here

使用SDK查询

  FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1 };
  var endpointUrl = "https://cosmosaccountName.documents.azure.com:443/";
  var primaryKey = "VNMIT4ydeC.....";
  var client = new DocumentClient(new Uri(endpointUrl), primaryKey);
  var sql = "SELECT * FROM root WHERE (ARRAY_CONTAINS(root.Tags, {\"Id\":\"686e4c9c-f1ab-40ce-8472-cc5d63597263\"},true) AND ARRAY_CONTAINS(root.Topics, {\"Id\":\"baa2c2a0-cc5b-42e3-9943-dcda776bdc20\"},true) AND root.Country  = \"UK\")";
  var profileQuery = client.CreateDocumentQuery<Profile>(
                UriFactory.CreateDocumentCollectionUri("dbname", "collectionName"),sql, queryOptions).AsDocumentQuery();

  var profileList = new List<Profile>();
   while (profileQuery.HasMoreResults)
   {
      profileList.AddRange(profileQuery.ExecuteNextAsync<Profile>().Result);

   }

enter image description here

Profile.cs文件

 public class Profile
    {
        [JsonProperty(PropertyName = "id")]
        public string Id { get; set; }

        public string Country { get; set; }

        public string ProfileName { get; set; }
        public Tag[] Tags{ get; set; }

        public Topic[] Topics { get; set; }

    }

<强> Topic.cs

public class Topic
    {
        public string Id { get; set; }
        public string Name { get; set; }

    }

<强> Tag.cs​​

public class Tag
    {
        public string Id { get; set; }
        public string Name { get; set; }

    }