当尝试使用 Azuren 搜索和 Azure Table 存储覆盖分区键时,.NET 收到错误请求

When trying to override Partition Key using Azuren Search and Azure Table Storage with .NET getting bad request

我正在使用 Azuren Search 和 Azure Table Storage 以及 .net,我正在尝试索引一个 table 并使分区键现在可以过滤,这在我尝试插入一些东西之前工作正常在那个 table 中,我收到一个没有太多附加信息的 BadRequest。 这是我的 class 波纹管

using System;
using Microsoft.Azure.Search;
using Microsoft.Azure.Search.Models;
using Microsoft.WindowsAzure.Storage.Table;

      [SerializePropertyNamesAsCamelCase]
    public class Asset : TableEntity
    {
        public Asset(string name)
        {
            Name = name;
        }

        public Asset()
        {

        }

        public Asset(string name, DateTimeOffset toBePublished, string pkey)
        {
            Name = name;
            ToBePublishedDate = toBePublished;
            PartitionKey = pkey;
        }

        [System.ComponentModel.DataAnnotations.Key]
        public string Id { get; set; } = DateTimeOffset.UtcNow.ToString("O")
            .Replace("+", string.Empty)
            .Replace(":", string.Empty)
            .Replace(".", string.Empty);

        [IsFilterable, IsSortable, IsSearchable]
        public new string PartitionKey { get; set; }

        [IsFilterable, IsSortable, IsSearchable]
        public string Name { get; set; } = "TemptAsset " + new Guid();

        [IsFilterable, IsSortable]
        public int? Version { get; set; } = 1;

        [IsFilterable, IsSortable]
        public DateTimeOffset? ToBePublishedDate { get; set; } = DateTimeOffset.UtcNow;

        [IsFilterable, IsSortable]
        public DateTimeOffset? ToBeRetiredDate { get; set; } = null;

        [IsFilterable, IsSearchable, IsSortable]
        public string Company { get; set; } = "TempCompany";
        [IsFilterable, IsSortable]
        public bool IsApproved { get; set; } = false;

        [IsFilterable, IsSortable]
        public bool IsDraft { get; set; } = true;


    }

这 运行s 并且索引创建成功见下文

现在,如果我尝试向该 table 添加一个实体,我会得到一个 BadRequest,但是通过在我的实体中注释掉 PartitionKey 来做完全相同的事情,这工作正常。 这就是我创建索引的方式

AzureSearch.CreateAssetNameIndex(AzureSearch.CreateSearchServiceClient());

    and the methods called bellow




using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using AssetSynch.Models;
    using Microsoft.Azure.Search;
    using Microsoft.Azure.Search.Models;
      public static SearchServiceClient CreateSearchServiceClient()
        {
            string searchServiceName = "*****";
            string adminApiKey = "********";

            SearchServiceClient serviceClient = new SearchServiceClient(searchServiceName,
                new SearchCredentials(adminApiKey));

            return serviceClient;
        }

    public static async void CreateAssetNameIndex(SearchServiceClient serviceClient)
        {
            Index definition = new Index
            {
                Name = "assetname",
                Fields = FieldBuilder.BuildForType<Asset>()
            };

            await serviceClient.Indexes.CreateAsync(definition);
        }

如果我 return 使用邮递员时出现错误,这是我得到的异常

      {
  "innerExceptions": [
    {
      "requestInformation": {
        "httpStatusCode": 400,
        "httpStatusMessage": "Bad Request",
        "serviceRequestID": "59efbc9a-0002-002c-3570-d5d55c000000",
        "contentMd5": null,
        "etag": null,
        "requestDate": "Thu, 25 May 2017 17:05:01 GMT",
        "targetLocation": 0,
        "extendedErrorInformation": {
          "errorCode": "PropertiesNeedValue",
          "errorMessage": "The values are not specified for all properties in the entity.\nRequestId:59efbc9a-0002-002c-3570-d5d55c000000\nTime:2017-05-25T16:05:06.5197909Z",
          "additionalDetails": {}
        },
        "isRequestServerEncrypted": false
      }
    }
  ]
}

如果我从我的实体中删除分区键并重新 运行 相同的代码以重新创建索引,则相同的代码段将成功执行。 我注意到的是,我的实体上现在有 2 个分区键,其中一个将保持为空,请参见下图,并且我的 属性 不会覆盖原始的。

这里有什么我遗漏的吗?

根据你的代码,我发现你的资产使用了new关键字来修改基础class的分区属性。

但这只会隐藏 base.partition 而不会覆盖它。

public new string PartitionKey { get; set; }

在Asset class中设置值后,您会发现它包含如下两个分区:

所以如果基class的分区键值为空,就会return 400错误。

因此,如果您想将新实体添加到 table,您需要设置基础 class(TableEntity) 分区键值。

所以我建议您可以如下更改您的资产:

  [SerializePropertyNamesAsCamelCase]
    public class Asset : TableEntity
    {
        public Asset(string name)
        {
            Name = name;
            base.PartitionKey = this.PartitionKey;
        }

        public Asset()
        {
            base.PartitionKey = this.PartitionKey;
        }

        public Asset(string name, DateTimeOffset toBePublished, string pkey)
        {

            Name = name;
            ToBePublishedDate = toBePublished;         
            PartitionKey = pkey;
            base.PartitionKey = this.PartitionKey;
        }

        [Key]
        [IsFilterable]
        public string Id { get; set; } = DateTimeOffset.UtcNow.ToString("O")
            .Replace("+", string.Empty)
            .Replace(":", string.Empty)
            .Replace(".", string.Empty);

        [IsFilterable, IsSortable, IsSearchable]
        public new string PartitionKey { get; set; }

        [IsFilterable, IsSortable, IsSearchable]
        public string Name { get; set; } = "TemptAsset " + new Guid();

        [IsFilterable, IsSortable]
        public int? Version { get; set; } = 1;

        [IsFilterable, IsSortable]
        public DateTimeOffset? ToBePublishedDate { get; set; } = DateTimeOffset.UtcNow;

        [IsFilterable, IsSortable]
        public DateTimeOffset? ToBeRetiredDate { get; set; } = null;

        [IsFilterable, IsSearchable, IsSortable]
        public string Company { get; set; } = "TempCompany";
        [IsFilterable, IsSortable]
        public bool IsApproved { get; set; } = false;

        [IsFilterable, IsSortable]
        public bool IsDraft { get; set; } = true;


    }

如果你想使用table存储作为数据源,我建议你可以参考这个article