FetchXml-Beispielcode
Um die Verwendung von FetchXml mit C# auszuprobieren, können Sie die statischen OutputFetchRequest
-Methoden in diesem Artikel verwenden, indem Sie die entsprechenden Schnellstartbeispiele anpassen:
Hinweis
Beispielcode zum Abrufen von Daten auf Seiten finden Sie unter Beispiele für Auslagerungs-Cookies.
Sie können die folgende statische OutputFetchRequest
-Methode verwenden, um FetchXml-Abfragen in einer Konsolenanwendung zu testen.
Die OutputFetchRequest
-Methode zeigt, wie die FetchExpression-Klasse und die IOrganizationService.RetrieveMultiple-Methode verwendet werden, um eine EntityCollection zurückzugeben, die die angeforderten Daten enthält.
Die OutputFetchRequest
-Methode hängt vom ConsoleTables-NuGet-Paket ab und erfordert, dass alle Entitäten oder Link-Entitätselemente Attributelemente enthalten sind, was eine bewährte Methode ist.
/// <summary>
/// Renders the output of a query in a table for a console application
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance to use.</param>
/// <param name="fetchXml">The FetchXml query to use.</param>
static void OutputFetchRequest(IOrganizationService service, string fetchXml)
{
FetchExpression fetchExpression = new(fetchXml);
//Retrieve the data
EntityCollection entityCollection = service.RetrieveMultiple(query: fetchExpression);
// Get column names from the FetchXml
List<string> columns = GetColumns(fetchXml);
// Create the table using https://www.nuget.org/packages/ConsoleTables/2.5.0
var table = new ConsoleTables.ConsoleTable(columns.ToArray());
// Add the rows of the table
entityCollection.Entities.ToList().ForEach(entity =>
{
table.Rows.Add(GetRowValues(columns, entity).ToArray());
});
// Write the table to the console
table.Write();
/// <summary>
/// Get a list of column names from the FetchXml
/// </summary>
/// <param name="fetchXml">The fetchXml query</param>
/// <returns></returns>
static List<string> GetColumns(string fetchXml)
{
XDocument fetchDoc = XDocument.Parse(fetchXml);
XElement fetchElement = fetchDoc.Root;
bool isAggregate = !(fetchElement?.Attributes("aggregate") == null &&
(fetchElement?.Attribute("aggregate")?.Value == "true" ||
fetchElement?.Attribute("aggregate")?.Value == "1"));
// There can only be one entity element
XElement entityElement = fetchElement.Element("entity");
// Get the columns from the entity and any related link-entity elements
return GetColumnsFromElement(element: entityElement, isAggregate: isAggregate);
}
/// <summary>
/// Recursive function to get all column names from an entity or nested link-entity elements
/// </summary>
/// <param name="element">The entity or link-entity element</param>
/// <param name="isAggregate">Whether the query uses aggregation</param>
/// <param name="alias">The alias of the link-entity element</param>
/// <returns></returns>
static List<string> GetColumnsFromElement(XElement element, bool isAggregate, string? alias = null)
{
List<string> columns = new();
// Get the attributes from the element
foreach (XElement attribute in element.Elements("attribute"))
{
StringBuilder sb = new();
// Prepend the alias for non-aggregate link-entities
if (!string.IsNullOrWhiteSpace(alias) && !isAggregate)
{
sb.Append($"{alias}.");
}
// Use the attribute alias if there is one
if (attribute.Attribute("alias") != null)
{
sb.Append(attribute.Attribute("alias")?.Value);
}
else
{
//Use the attribute name
sb.Append(attribute.Attribute("name")?.Value);
}
columns.Add(sb.ToString());
}
// Whether the link-entity intersect attribute is true
bool isIntersect = (element.Attribute("intersect") != null) &&
(element.Attribute("intersect")?.Value == "true" ||
element.Attribute("intersect")?.Value == "1");
// The name of the element
string elementName = element.Attribute("name")?.Value;
// The type of element: 'entity' or 'link-entity'
string elementType = element.Name.LocalName;
// This method requires any non-intersect entity to have attributes
if (columns.Count == 0 && !isIntersect)
{
// An non-intersect element with no attribute elements is technically valid,
// but not supported by this method.
throw new Exception($"No attribute elements in {elementType} element named '{elementName}'.");
}
// Look for any child link-entities
foreach (XElement linkEntity in element.Elements("link-entity"))
{
// Use the alias if any
string? linkEntityName;
if (linkEntity.Attribute("alias") != null)
{
linkEntityName = linkEntity.Attribute("alias")?.Value;
}
else
{
linkEntityName = linkEntity.Attribute("name")?.Value;
}
// Recursive call for nested link-entity elements
columns.AddRange(GetColumnsFromElement(linkEntity, isAggregate, linkEntityName));
}
return columns;
}
/// <summary>
/// Returns the values of a row as strings
/// </summary>
/// <param name="columns">The names of the columns</param>
/// <param name="entity">The entity with the data</param>
/// <returns></returns>
static List<string> GetRowValues(List<string> columns, Entity entity)
{
List<string> values = new();
columns.ForEach(column =>
{
if (entity.Attributes.ContainsKey(column))
{
// Use the formatted value if it available
if (entity.FormattedValues.ContainsKey(column) &&
!string.IsNullOrWhiteSpace(entity.FormattedValues[column]))
{
values.Add($"{entity.FormattedValues[column]}");
}
else
{
// When an alias is used, the Aliased value must be converted
if (entity.Attributes[column] is AliasedValue aliasedValue)
{
// When an EntityReference doesn't have a Name, show the Id
if (aliasedValue.Value is EntityReference lookup &&
string.IsNullOrWhiteSpace(lookup.Name))
{
values.Add($"{lookup.Id:B}");
}
else
{
values.Add($"{aliasedValue.Value}");
}
}
else
{
// Use the simple attribute value
values.Add($"{entity.Attributes[column]}");
}
}
}
// Null values are not in the Attributes collection
else
{
values.Add("NULL");
}
});
return values;
}
}
SDK für .NET-Schnellstartbeispiel aktualisieren
Sie können das Beispiel Schnellstart: Eine SDK für .NET-Anforderung ausführen (C#) zum Testen von Abfragen mit den folgenden Schritten anpassen:
ConsoleTables-NuGet-Paket installieren
Fügen Sie die folgenden Anweisungen mithilfe von Anweisungen an den Anfang der Datei
program.cs
ein.using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; using System.Text; using System.Xml.Linq;
Kopieren Sie die Methode
OutputFetchRequest
und fügen Sie sie unter der MethodeMain
ein.Bearbeiten Sie die
Main
-Methode, um Ihre Abfrage festzulegen, und verwenden Sie dieOutputFetchRequest
-Methode.static void Main(string[] args) { using (ServiceClient serviceClient = new(connectionString)) { if (serviceClient.IsReady) { //WhoAmIResponse response = // (WhoAmIResponse)serviceClient.Execute(new WhoAmIRequest()); //Console.WriteLine("User ID is {0}.", response.UserId); string fetchQuery = @"<fetch top='5'> <entity name='account'> <attribute name='accountclassificationcode' /> <attribute name='createdby' /> <attribute name='createdon' /> <attribute name='name' /> </entity> </fetch>"; OutputFetchRequest(serviceClient, fetchQuery); } else { Console.WriteLine( "A web service connection was not established."); } } // Pause the console so it does not close. Console.WriteLine("Press the <Enter> key to exit."); Console.ReadLine(); }
Wenn Sie das Programm mit der OutputFetchRequest
-Methode ausführen, sollte die Ausgabe wie folgt aussehen:
---------------------------------------------------------------------------------------------------------
| accountclassificationcode | createdby | createdon | name |
---------------------------------------------------------------------------------------------------------
| Default Value | FirstName LastName | 3/25/2023 10:42 AM | Litware, Inc. (sample) |
---------------------------------------------------------------------------------------------------------
| Default Value | FirstName LastName | 3/25/2023 10:42 AM | Adventure Works (sample) |
---------------------------------------------------------------------------------------------------------
| Default Value | FirstName LastName | 3/25/2023 10:42 AM | Fabrikam, Inc. (sample) |
---------------------------------------------------------------------------------------------------------
| Default Value | FirstName LastName | 3/25/2023 10:42 AM | Blue Yonder Airlines (sample) |
---------------------------------------------------------------------------------------------------------
| Default Value | FirstName LastName | 3/25/2023 10:42 AM | City Power & Light (sample) |
---------------------------------------------------------------------------------------------------------
Ähnliche Artikel
Daten mithilfe von FetchXml abfragen
Daten mithilfe von FetchXml abrufen
Beispiel: Verwendung FetchXML mit einem Paging-Cookie
Beispiel: Verwenden Sie Aggregation in FetchXML
Beispiel: Konvertieren von Abfragen zwischen FetchXML und QueryExpression