microsoft / PowerPlatform-DataverseServiceClient

Code Replica for Microsoft.PowerPlatform.Dataverse.Client and supporting nuget packages.
MIT License
285 stars 52 forks source link

'ServiceClient' does not contain a definition for 'RetreiveMultiple' #309

Closed RODINOliver closed 2 years ago

RODINOliver commented 2 years ago

Hi Team,

I am currently trying to utilise Microsoft.PowerPlatform.Dataverse.Client within an Azure Function to query if rows exist with specific criteria.

I keep running into issues with the 'ServiceClient' not having the 'RetrieveMultiple' definition.

As far as I can tell the definition should be recognised as it can be found here in the ServiceClient.cs file.

I could be missing something entirely, so would appreciate any advice.

End goal is as described above, just want to have an Azure Function which is able to run a lookup query as opposed to retrieve a specific entity right away.

I am using Managed Identity authentication if that has an affect on things -

var serviceClient = new ServiceClient(ConfigHandler.DataverseUrl, async (string dataverseUri) => {
   return await AuthenticationHandler.GetAccessTokenAsync(dataverseUri);
}, true);
if (!serviceClient.IsReady) throw new Exception("Authentication Failed!");

The code segment which is triggering the error is -

var query = new QueryExpression("cr487_sbatattendee")
{
   ColumnSet = new ColumnSet("cr487_SBATAttendeeSBACFirstName"),
   Criteria = new FilterExpression(LogicalOperator.And),
   TopCount = 50
};
query.Criteria.AddCondition("cr487_SBATAttendeeSBACLastName", ConditionOperator.Equal, "Howse");
EntityCollection results = serviceClient.RetreiveMultiple(query);

The directives I am using as well are -

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.PowerPlatform.Dataverse.Client;
using DotNetCore.Handlers;
using Schema.AttendeeCheck;
using Microsoft.Extensions.Configuration;

Interested in your thoughts, cheers!

fowl2 commented 2 years ago

Can you post your project file, packages.config (if applicable) and the full text of the exception?

RODINOliver commented 2 years ago

Sure, the error is - error CS1061: 'ServiceClient' does not contain a definition for 'RetreiveMultiple' and no accessible extension method 'RetreiveMultiple' accepting a first argument of type 'ServiceClient' could be found (are you mis sing a using directive or an assembly reference?) [C:\SBA\Medical Information AF\Medical Information AF.csproj]

Medical Information AF.csproj -

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
    <RootNamespace>Medical_Information_AF</RootNamespace>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Azure.Identity" Version="1.6.1" />
    <PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.9" />
    <PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
    <PackageReference Include="Microsoft.Azure.KeyVault" Version="3.0.5" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.OpenApi" Version="1.4.0" />
    <PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.1" />
    <PackageReference Include="Microsoft.PowerPlatform.Dataverse.Client" Version="1.0.9" />
    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
    <PackageReference Include="Xrm.Tools.CRMWebAPI" Version="1.0.25" />
  </ItemGroup>
  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>
fowl2 commented 2 years ago

Did you mean "RetrieveMultiple" instead of "RetreiveMultiple"? 😅

RODINOliver commented 2 years ago

Well, that's awkward, apparently I have dyslexia... thanks for picking up on my mistake!

Fixed typo and is working as expected now.

jordimontana82 commented 2 years ago

@RODINOliver it might be best if you use the IOrganizationService or IOrganizationServiceAsync interfaces (both of them are implemented by ServiceClient) though, cause it'll make it easier to unit test ....

RODINOliver commented 2 years ago

Do you have a link to an example using those interfaces?

The documentation here seems to mention 'SampleCode\CS\BusinessDataModel\Templates\GetEmailTemplateAttachments.cs' but I'm not sure where that actually is.

jordimontana82 commented 2 years ago

Do you have a link to an example using those interfaces?

ServiceClient implements both so you could assign it upon initialisation, like:

IOrganizationService orgService = new ServiceClient(...)

IOrganizationServiceAsync orgService = new ServiceClient(...)

RODINOliver commented 2 years ago

Is there another 'using' definition needed to use IOrganizationService / IOrganizationServiceAsync?

jordimontana82 commented 2 years ago

Nope, they are in the same namespace...

https://github.com/microsoft/PowerPlatform-DataverseServiceClient/blob/254952f3a781f1ab363c56f1a43c4d9b49652fed/src/GeneralTools/DataverseClient/Client/Interfaces/IOrganizationServiceAsync.cs#L8-L16

https://github.com/microsoft/PowerPlatform-DataverseServiceClient/blob/254952f3a781f1ab363c56f1a43c4d9b49652fed/src/GeneralTools/DataverseClient/Client/ServiceClient.cs#L42

RODINOliver commented 2 years ago

So currently I have -

var serviceClient = new ServiceClient(ConfigHandler.DataverseUrl, async (string dataverseUri) => {
   return await AuthenticationHandler.GetAccessTokenAsync(dataverseUri);
}, true);

Is it really as simple as changing var serviceClient to IOrganizationServiceAsync orgService

I did try it but I would've thought that the advantage would be orgService then having better intellisense or similar, but I might be missing the point entirely...

jordimontana82 commented 2 years ago

Is it really as simple as changing var serviceClient to IOrganizationServiceAsync orgService

Yep, that's it. You would get intellisense of the methods available on IOrganizationService / Async versions...