Uppgradera till Azure Search .NET SDK version 1.1
Om du använder version 1.0.2-preview eller äldre av Azure Search .NET SDK hjälper den här artikeln dig att uppgradera ditt program så att det använder version 1.1.
En mer allmän genomgång av SDK inklusive exempel finns i Så här använder du Azure Search från ett .NET-program.
Anteckning
När du har uppgraderat till version 1.1 eller om du redan använder en version mellan 1.1 och 2.0-preview bör du uppgradera till version 3. Anvisningar finns i Uppgradera till Azure Search .NET SDK version 3 .
Uppdatera först NuGet-referensen för Microsoft.Azure.Search
att antingen använda NuGet Package Manager-konsolen eller genom att högerklicka på dina projektreferenser och välja "Hantera NuGet-paket..." i Visual Studio.
När NuGet har laddat ned de nya paketen och deras beroenden återskapar du projektet.
Om du tidigare använde version 1.0.0-preview, 1.0.1-preview eller 1.0.2-preview bör versionen lyckas och du är redo!
Om du tidigare använde version 0.13.0-preview eller äldre bör du se build-fel som följande:
Program.cs(137,56,137,62): error CS0117: 'Microsoft.Azure.Search.Models.IndexBatch' does not contain a definition for 'Create'
Program.cs(137,99,137,105): error CS0117: 'Microsoft.Azure.Search.Models.IndexAction' does not contain a definition for 'Create'
Program.cs(146,41,146,54): error CS1061: 'Microsoft.Azure.Search.IndexBatchException' does not contain a definition for 'IndexResponse' and no extension method 'IndexResponse' accepting a first argument of type 'Microsoft.Azure.Search.IndexBatchException' could be found (are you missing a using directive or an assembly reference?)
Program.cs(163,13,163,42): error CS0246: The type or namespace name 'DocumentSearchResponse' could not be found (are you missing a using directive or an assembly reference?)
Nästa steg är att åtgärda byggfelen en i taget. De flesta kräver att vissa klass- och metodnamn ändras som har bytt namn i SDK:et. Listan över icke-bakåtkompatibla ändringar i version 1.1 innehåller en lista över dessa namnändringar.
Om du använder anpassade klasser för att modellera dina dokument, och dessa klasser har egenskaper för primitiva typer som inte kan ha null-värde (till exempel int
eller bool
i C#), finns det en felkorrigering i 1.1-versionen av SDK som du bör känna till. Mer information finns i Felkorrigeringar i version 1.1 .
När du har åtgärdat eventuella byggfel kan du slutligen göra ändringar i ditt program för att dra nytta av nya funktioner om du vill.
Lista över icke-bakåtkompatibla ändringar i version 1.1
Följande lista sorteras efter sannolikheten att ändringen påverkar programkoden.
IndexBatch- och IndexAction-ändringar
IndexBatch.Create
har bytt namn till IndexBatch.New
och har inte längre något params
argument. Du kan använda IndexBatch.New
för batchar som blandar olika typer av åtgärder (sammanslagningar, borttagningar osv.). Dessutom finns det nya statiska metoder för att skapa batchar där alla åtgärder är desamma: Delete
, Merge
, MergeOrUpload
och Upload
.
IndexAction
har inte längre offentliga konstruktorer och dess egenskaper är nu oföränderliga. Du bör använda de nya statiska metoderna för att skapa åtgärder för olika syften: Delete
, Merge
, MergeOrUpload
och Upload
.
IndexAction.Create
har tagits bort. Om du använde överbelastningen som bara tar ett dokument ska du använda Upload
i stället.
Exempel
Om koden ser ut så här:
var batch = IndexBatch.Create(documents.Select(doc => IndexAction.Create(doc)));
indexClient.Documents.Index(batch);
Du kan ändra det till detta för att åtgärda eventuella byggfel:
var batch = IndexBatch.New(documents.Select(doc => IndexAction.Upload(doc)));
indexClient.Documents.Index(batch);
Om du vill kan du förenkla det ytterligare så här:
var batch = IndexBatch.Upload(documents);
indexClient.Documents.Index(batch);
IndexBatchException-ändringar
Egenskapen IndexBatchException.IndexResponse
har bytt namn till IndexingResults
och dess typ är nu IList<IndexingResult>
.
Exempel
Om koden ser ut så här:
catch (IndexBatchException e)
{
Console.WriteLine(
"Failed to index some of the documents: {0}",
String.Join(", ", e.IndexResponse.Results.Where(r => !r.Succeeded).Select(r => r.Key)));
}
Du kan ändra det till detta för att åtgärda eventuella byggfel:
catch (IndexBatchException e)
{
Console.WriteLine(
"Failed to index some of the documents: {0}",
String.Join(", ", e.IndexingResults.Where(r => !r.Succeeded).Select(r => r.Key)));
}
Ändringar av åtgärdsmetod
Varje åtgärd i Azure Search .NET SDK exponeras som en uppsättning metodöverlagringar för synkrona och asynkrona anropare. Signaturer och faktorering för dessa metodöverlagringar har ändrats i version 1.1.
Åtgärden "Hämta indexstatistik" i äldre versioner av SDK exponerade till exempel dessa signaturer:
Följande gäller i IIndexOperations
:
// Asynchronous operation with all parameters
Task<IndexGetStatisticsResponse> GetStatisticsAsync(
string indexName,
CancellationToken cancellationToken);
Följande gäller i IndexOperationsExtensions
:
// Asynchronous operation with only required parameters
public static Task<IndexGetStatisticsResponse> GetStatisticsAsync(
this IIndexOperations operations,
string indexName);
// Synchronous operation with only required parameters
public static IndexGetStatisticsResponse GetStatistics(
this IIndexOperations operations,
string indexName);
Metodsignaturerna för samma åtgärd i version 1.1 ser ut så här:
Följande gäller i IIndexesOperations
:
// Asynchronous operation with lower-level HTTP features exposed
Task<AzureOperationResponse<IndexGetStatisticsResult>> GetStatisticsWithHttpMessagesAsync(
string indexName,
SearchRequestOptions searchRequestOptions = default(SearchRequestOptions),
Dictionary<string, List<string>> customHeaders = null,
CancellationToken cancellationToken = default(CancellationToken));
Följande gäller i IndexesOperationsExtensions
:
// Simplified asynchronous operation
public static Task<IndexGetStatisticsResult> GetStatisticsAsync(
this IIndexesOperations operations,
string indexName,
SearchRequestOptions searchRequestOptions = default(SearchRequestOptions),
CancellationToken cancellationToken = default(CancellationToken));
// Simplified synchronous operation
public static IndexGetStatisticsResult GetStatistics(
this IIndexesOperations operations,
string indexName,
SearchRequestOptions searchRequestOptions = default(SearchRequestOptions));
Från och med version 1.1 organiserar Azure Search .NET SDK åtgärdsmetoder på olika sätt:
- Valfria parametrar modelleras nu som standardparametrar i stället för ytterligare metodöverlagringar. Detta minskar antalet metodöverbelastningar, ibland dramatiskt.
- Tilläggsmetoderna döljer nu mycket av den överflödiga informationen om HTTP från anroparen. Till exempel returnerade äldre versioner av SDK ett svarsobjekt med en HTTP-statuskod, som du ofta inte behövde kontrollera eftersom åtgärdsmetoderna genererar
CloudException
statuskod som indikerar ett fel. De nya tilläggsmetoderna returnerar bara modellobjekt, vilket gör att du slipper packa upp dem i koden. - På motsvarande sätt exponerar kärngränssnitten nu metoder som ger dig mer kontroll på HTTP-nivå om du behöver det. Du kan nu skicka in anpassade HTTP-huvuden som ska inkluderas i begäranden, och den nya
AzureOperationResponse<T>
returtypen ger dig direkt åtkomst tillHttpRequestMessage
ochHttpResponseMessage
för åtgärden.AzureOperationResponse
definieras iMicrosoft.Rest.Azure
namnområdet och ersätterHyak.Common.OperationResponse
.
Ändringar i ScoringParameters
En ny klass med namnet ScoringParameter
har lagts till i den senaste SDK:n för att göra det enklare att ange parametrar för bedömningsprofiler i en sökfråga.
ScoringProfiles
Tidigare skrevs egenskapen för SearchParameters
klassen som IList<string>
; Nu skrivs den som IList<ScoringParameter>
.
Exempel
Om koden ser ut så här:
var sp = new SearchParameters();
sp.ScoringProfile = "jobsScoringFeatured"; // Use a scoring profile
sp.ScoringParameters = new[] { "featuredParam-featured", "mapCenterParam-" + lon + "," + lat };
Du kan ändra det till detta för att åtgärda eventuella byggfel:
var sp = new SearchParameters();
sp.ScoringProfile = "jobsScoringFeatured"; // Use a scoring profile
sp.ScoringParameters =
new[]
{
new ScoringParameter("featuredParam", new[] { "featured" }),
new ScoringParameter("mapCenterParam", GeographyPoint.Create(lat, lon))
};
Modellklassändringar
På grund av signaturändringarna som beskrivs i Åtgärdsmetodändringar har många klasser i Microsoft.Azure.Search.Models
namnområdet bytt namn eller tagits bort. Exempel:
-
IndexDefinitionResponse
har ersatts avAzureOperationResponse<Index>
-
DocumentSearchResponse
har bytt namn tillDocumentSearchResult
-
IndexResult
har bytt namn tillIndexingResult
-
Documents.Count()
returnerar nu enlong
med antalet dokument i stället för enDocumentCountResponse
-
IndexGetStatisticsResponse
har bytt namn tillIndexGetStatisticsResult
-
IndexListResponse
har bytt namn tillIndexListResult
Sammanfattnings nog OperationResponse
har -härledda klasser som endast fanns för att omsluta ett modellobjekt tagits bort. De återstående klasserna har fått sitt suffix ändrat från Response
till Result
.
Exempel
Om koden ser ut så här:
IndexerGetStatusResponse statusResponse = null;
try
{
statusResponse = _searchClient.Indexers.GetStatus(indexer.Name);
}
catch (Exception ex)
{
Console.WriteLine("Error polling for indexer status: {0}", ex.Message);
return;
}
IndexerExecutionResult lastResult = statusResponse.ExecutionInfo.LastResult;
Du kan ändra det till detta för att åtgärda eventuella byggfel:
IndexerExecutionInfo status = null;
try
{
status = _searchClient.Indexers.GetStatus(indexer.Name);
}
catch (Exception ex)
{
Console.WriteLine("Error polling for indexer status: {0}", ex.Message);
return;
}
IndexerExecutionResult lastResult = status.LastResult;
Svarsklasser och IEnumerable
En ytterligare ändring som kan påverka din kod är att svarsklasser som innehåller samlingar inte längre implementerar IEnumerable<T>
. I stället kan du komma åt samlingsegenskapen direkt. Om koden till exempel ser ut så här:
DocumentSearchResponse<Hotel> response = indexClient.Documents.Search<Hotel>(searchText, sp);
foreach (SearchResult<Hotel> result in response)
{
Console.WriteLine(result.Document);
}
Du kan ändra det till detta för att åtgärda eventuella byggfel:
DocumentSearchResult<Hotel> response = indexClient.Documents.Search<Hotel>(searchText, sp);
foreach (SearchResult<Hotel> result in response.Results)
{
Console.WriteLine(result.Document);
}
Specialfall för webbprogram
Om du har ett webbprogram som serialiseras DocumentSearchResponse
direkt för att skicka sökresultat till webbläsaren måste du ändra koden, annars serialiseras resultaten inte korrekt. Om koden till exempel ser ut så här:
public ActionResult Search(string q = "")
{
// If blank search, assume they want to search everything
if (string.IsNullOrWhiteSpace(q))
q = "*";
return new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = _featuresSearch.Search(q)
};
}
Du kan ändra det genom att hämta .Results
egenskapen för söksvaret för att åtgärda sökresultatåtergivningen:
public ActionResult Search(string q = "")
{
// If blank search, assume they want to search everything
if (string.IsNullOrWhiteSpace(q))
q = "*";
return new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = _featuresSearch.Search(q).Results
};
}
Du måste leta efter sådana fall i din kod själv; Kompilatorn varnar dig inte eftersom JsonResult.Data
är av typen object
.
CloudException-ändringar
Klassen CloudException
har flyttats från Hyak.Common
namnområdet till Microsoft.Rest.Azure
namnområdet. Dessutom har dess Error
egenskap bytt namn till Body
.
SearchServiceClient- och SearchIndexClient-ändringar
Egenskapens Credentials
typ har ändrats från SearchCredentials
till dess basklass, ServiceClientCredentials
. Om du behöver åtkomst SearchCredentials
till för en SearchIndexClient
eller SearchServiceClient
använder du den nya SearchCredentials
egenskapen.
I äldre versioner av SDK SearchServiceClient
och SearchIndexClient
hade konstruktorer som tog en HttpClient
parameter. Dessa har ersatts med konstruktorer som tar en HttpClientHandler
och en matris med DelegatingHandler
objekt. Detta gör det enklare att installera anpassade hanterare för att förbearbeta HTTP-begäranden om det behövs.
Slutligen har konstruktorerna som tog en Uri
och SearchCredentials
ändrats. Om du till exempel har kod som ser ut så här:
var client =
new SearchServiceClient(
new SearchCredentials("abc123"),
new Uri("http://myservice.search.windows.net"));
Du kan ändra det till detta för att åtgärda eventuella byggfel:
var client =
new SearchServiceClient(
new Uri("http://myservice.search.windows.net"),
new SearchCredentials("abc123"));
Observera också att typen av parameter för autentiseringsuppgifter har ändrats till ServiceClientCredentials
. Det här kommer sannolikt inte att påverka koden eftersom SearchCredentials
den härleds från ServiceClientCredentials
.
Skicka ett begärande-ID
I äldre versioner av SDK:n kan du ange ett begärande-ID för SearchServiceClient
eller SearchIndexClient
och det skulle inkluderas i varje begäran till REST-API:et. Detta är användbart för felsökning av problem med söktjänsten om du behöver kontakta supporten. Det är dock mer användbart att ange ett unikt begärande-ID för varje åtgärd i stället för att använda samma ID för alla åtgärder. Därför har metoderna SearchServiceClient
för SetClientRequestId
och SearchIndexClient
tagits bort. I stället kan du skicka ett begärande-ID till varje åtgärdsmetod via den valfria SearchRequestOptions
parametern .
Anteckning
I en framtida version av SDK lägger vi till en ny mekanism för att ange ett begärande-ID globalt på klientobjekten som överensstämmer med den metod som används av andra Azure-SDK:er.
Exempel
Om du har kod som ser ut så här:
client.SetClientRequestId(Guid.NewGuid());
...
long count = client.Documents.Count();
Du kan ändra det till detta för att åtgärda eventuella byggfel:
long count = client.Documents.Count(new SearchRequestOptions(requestId: Guid.NewGuid()));
Ändringar av gränssnittsnamn
Gränssnittsnamnen för åtgärdsgruppen har ändrats så att de överensstämmer med deras motsvarande egenskapsnamn:
- Typen av
ISearchServiceClient.Indexes
har bytt namn frånIIndexOperations
tillIIndexesOperations
. - Typen av
ISearchServiceClient.Indexers
har bytt namn frånIIndexerOperations
tillIIndexersOperations
. - Typen av
ISearchServiceClient.DataSources
har bytt namn frånIDataSourceOperations
tillIDataSourcesOperations
. - Typen av
ISearchIndexClient.Documents
har bytt namn frånIDocumentOperations
tillIDocumentsOperations
.
Den här ändringen kommer sannolikt inte att påverka koden om du inte har skapat modeller av dessa gränssnitt i testsyfte.
Felkorrigeringar i version 1.1
Det uppstod en bugg i äldre versioner av Azure Search .NET SDK som rör serialisering av anpassade modellklasser. Felet kan inträffa om du har skapat en anpassad modellklass med en egenskap av en värdetyp som inte kan ha värdet null.
Steg för att återskapa
Skapa en anpassad modellklass med en egenskap av värdetypen som inte kan ha värdet null. Lägg till exempel till en offentlig UnitCount
egenskap av typen int
i stället för int?
.
Om du indexar ett dokument med standardvärdet för den typen (till exempel 0 för int
) blir fältet null i Azure Search. Om du sedan söker efter dokumentet utlöser anropet Search
ett klagomål om att det inte kan konverteras null
till int
.JsonSerializationException
Filter kanske inte heller fungerar som förväntat eftersom null skrevs till indexet i stället för det avsedda värdet.
Åtgärda information
Vi har åtgärdat det här problemet i version 1.1 av SDK. Om du nu har en modellklass som den här:
public class Model
{
public string Key { get; set; }
public int IntValue { get; set; }
}
och du anger IntValue
till 0, det värdet är nu korrekt serialiserat som 0 på kabeln och lagras som 0 i indexet. Rund tripping fungerar också som förväntat.
Det finns ett potentiellt problem att vara medveten om med den här metoden: Om du använder en modelltyp med en egenskap som inte kan ha värdet null måste du garantera att inga dokument i indexet innehåller ett null-värde för motsvarande fält. Varken SDK:n eller REST-API:et för Azure Search hjälper dig att framtvinga detta.
Detta är inte bara ett hypotetiskt problem. Tänk dig ett scenario där du lägger till ett nytt fält till ett befintligt index som är av typen Edm.Int32
. När du har uppdaterat indexdefinitionen har alla dokument ett null-värde för det nya fältet (eftersom alla typer kan vara null i Azure Search). Om du sedan använder en modellklass med en icke-nullbar int
-egenskap för det fältet returneras ett JsonSerializationException
som detta när du försöker hämta dokument:
Error converting value {null} to type 'System.Int32'. Path 'IntValue'.
Därför rekommenderar vi fortfarande att du använder typer som kan ha värdet null i dina modellklasser som bästa praxis.
Mer information om felet och korrigeringen finns i det här problemet på GitHub.