0

We have to change the way we retrieve our data - currently it comes from a SQL server, but there is now a 'golden source' available where the data is broken down into relevant objects, i.e. Country, Worker, Worker Account and Active Directory. This is a sample of the JSON for Country:

{
"@odata.context": "https://this.company.url/WebAPI/v2/$metadata#Country",
"value": [
    {
        "CountryId": 100002,
        "CountryAlpha2Code": "AD",
        "CountryAlpha3Code": "AND",
        "CountryNumericCode": "020",
        "CountryName": "Andorra",
        "CountryStartDate": null,
        "CountryEndDate": null,
        "RetiredCountryCode": null,
        "CountryShortName": "Andorra",
        "IsDeleted": false,
        "LastUpdateTime": "2017-08-05T09:58:53.44Z",
        "LastUpdateBy": "USERID",
        "ETLUpdatedDate": "2018-08-18T04:58:31Z"
    },
    {
        "CountryId": 100003,
        "CountryAlpha2Code": "AE",
        "CountryAlpha3Code": "ARE",
        "CountryNumericCode": "784",
        "CountryName": "United Arab Emirates (the)",
        "CountryStartDate": null,
        "CountryEndDate": null,
        "RetiredCountryCode": null,
        "CountryShortName": "United Arab Emirates",
        "IsDeleted": false,
        "LastUpdateTime": "2017-08-05T09:58:53.44Z",
        "LastUpdateBy": "USERID",
        "ETLUpdatedDate": "2018-08-18T04:58:31Z"
    },
    {...

If I then copy the JSON as classes, I get

public class Rootobject
{
    public string odatacontext { get; set; }
    public Value[] value { get; set; }
}

public class Value
{
    public int CountryId { get; set; }
    public string CountryAlpha2Code { get; set; }
    public string CountryAlpha3Code { get; set; }
    public string CountryNumericCode { get; set; }
...
    public string LastUpdateBy { get; set; }
    public DateTime ETLUpdatedDate { get; set; }
}

I've found an example but having five different objects, which all have the same rootobject and value classes, am struggling to implement this. I have no control over the structure of the JSON metadata as I'm not the only person using it, so I'm trying to figure out how I can read each class, keeping them distinct.
FYI this is the query I'm wanting to replicate (though one of the classes isn't available yet - FinancialGeographyAddress, but there is enough work to keep me busy whilst that is being made available).

SELECT 
UPPER(AD.[AccountName])
,TRIM('.' FROM AD.[LastName]) AS [LastName]
,TRIM('.' FROM AD.[GivenName]) AS [GivenName]
,TRIM('.' FROM AD.[Initials]) AS [Initials]
,LOWER(AD.[EmailAddress])
,C.[CountryAlpha2Code]
,AD.[DisplayName]
,AD.[Enabled]
,CASE
    -- Swap display name to be 'lastname, firstname' when 'firstname lastname'
    WHEN AD.[DisplayName] IS NULL OR AD.[GivenName] = LEFT(AD.[DisplayName], LEN(AD.[GivenName])) THEN
        [LastName] + ', ' + [GivenName]
    -- Remove the bracketed suffix and/or any trailing periods
    WHEN CHARINDEX('(', AD.[DisplayName]) > 0 THEN
        TRIM('.' FROM LEFT(AD.[DisplayName], CHARINDEX('(', AD.[DisplayName]) - 2))
    ELSE
        TRIM('.' FROM AD.[DisplayName])
    END  
FROM [wrk].[vwWorker] AS W
INNER JOIN [rpt].[vwFinancialGeographyAddress] AS FGA 
    ON W.[FinancialGeographyId] = FGA.[FinancialGeographyId] AND FGA.[IsDeleted] = 0
INNER JOIN [rpt].[vwCountry] AS C ON C.[CountryId] = FGA.[CountryId] AND C.[IsDeleted] = 0
INNER JOIN [wrk].[vwWorkerAccount] AS WA ON WA.[WorkerId] = W.[WorkerId] AND WA.[IsDeleted] = 0
INNER JOIN [rpt].[vwActiveDirectory] AS AD ON AD.[ActiveDirectoryId] = WA.[ActiveDirectoryID] 
                                                AND AD.[IsDeleted] = 0 AND AD.[Enabled] = 'True' 
WHERE 
-- Only interested in UK, Guernsey and Ireland
C.[CountryAlpha2Code] IN ('GB', 'GG', 'IE')
5
  • The question is unclear. How you serialize objects to JSON has nothing to do with databases and queries. What you posted though isn't just JSON, it's an OData response which means you're calling an OData service with a specific schema, navigations and allowed queries. You can find that schema at .../$metadata. You can even create a client automatically in Visual Studio with Add Connected Services that will convert LINQ queries to OData URLs. You can't perform arbitrary queries though. Commented Jul 5, 2024 at 8:00
  • Thanks, but that is the issue I have - adding a connected service doesn't work because the developers haven't set it up to be able to access it that way (not in their skill set) so I'm looking at alternatives. If it can't be accessed any other way, then I will have to go back to them. Commented Jul 5, 2024 at 8:24
  • They don't have to do anything. When they create an OData service the metadata is there simply because the OData library puts it there, at https://this.company.url/WebAPI/v2/$metadata. It's the client developer that can use Add Connected Service to the client proxy automatically. Or you can use the command line tools to generate the client and classes. Commented Jul 5, 2024 at 8:29
  • The question would be unclear even if it was only about JSON serialization. You can map JSON to different object types. Complex objects will have properties that are objects themselves. Querying an OData services though means you have to know the schema in advance so you can write the OData query. You can't use arbitrary JOINs. In the OData query example the actual query is the ULR /People?$expand=Trips&$filter=FirstName eq 'Peter'&$orderby=Firstname asc&$skip=3&$top=3 Commented Jul 5, 2024 at 8:37
  • Using $expand is similar to LINQ's Include: it tells the service to load the related entity. How that happens is entirely up to that service. $expand doesn't map or imply JOINs, or even that the same database will be used. Commented Jul 5, 2024 at 8:40

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.