This is a bit of a multi-faceted question, so let me just dive into the code with some explanation at the bottom.
Example Sample Data:
List<Encounter> input
Id, Facility, HospitalService, Field3, Field4, Field5, ...
1, 1, A, ..., ..., ...
2, 2, A, ..., ..., ...
3, 1, B, ..., ..., ...
4, 2, B, ..., ..., ...
5, 1, A, ..., ..., ...
5, 2, A, ..., ..., ...
What I want to do is query my data object and e.g. return back the distinct fields, e.g.
distinct Facility is 1, 2
distinct HospitalService is A, B
distinct pair is 1A, 2A, 1B, 2B
However, one gotcha is I want to return back a strongly typed object, and in this case, the same object as the input, in this case, the Encounter object, with all the other fields with empty or default values, e.g.
List<Encounter> output, with only fields of interest populated
Id, Facility, HospitalService, Field3, Field4, Field5, ...
0, 1, A, "", "", ""
0, 2, A, "", "", ""
0, 1, B, "", "", ""
0, 2, B, "", "", ""
With Standard LINQ, I can do this and it works.
List<Encounter> sampleData = CreateSampleData();
List<Encounter> rawResultFromStandardLinq =
sampleData
.GroupBy(e => new {e.Facility, e.HospitalService})
.Select(e => new Encounter() { Facility = e.Key.Facility, HospitalService = e.Key.HospitalService})
.ToList();
Question #1: In the above example, it is not dynamic. I had to know which object to create with the new keyword. Further, I had to know which fields to select/project. How can I do this dynamically? How can I project an anonymous type to a strong type?
e.g. I thought I could do something like this to use json serialization. This works, but I presume it would be very slow.
var rawResultAsAnonymousType =
sampleData
.GroupBy(e => new { e.Facility, e.HospitalService })
.Select(e => new { e.Key.Facility, e.Key.HospitalService })
.ToList();
string json = JsonConvert.SerializeObject(rawResultAsAnonymousType);
var encountersFromJson = JsonConvert.DeserializeObject<List<Encounter>>(json);
Question #2: The next problem we have is that we want the query to be dynamic. i.e. we want to expose an interface that will let the client query the data to get whatever they want. For that purpose, we have turned to Dynamic LINQ.
Can someone help me to get this to work?
[Update: I can now do this for multiple columns]
var rawResultFromDynamicLinq4 =
DynamicQueryable
.GroupBy(_sampleData.AsQueryable(), @"new (Facility, HospitalService)", "it")
.Select("new (it.Key.Facility, it.Key.HospitalService)")
;
[Before, I was trying to do this]
var rawResultFromDynamicLinq =
sampleData
.GroupByMany("Facility", "HospitalService")
//.Select(.... how do I get my object back?)
;
Some explanation:
Why are we doing it like this? It's largely irrelevant to the technical question, but if you must know, I work in healthcare and we are using the FHIR standards to query data, so we have to use the defined FHIR models. This means we can't just return back a List that contains distinct values of a particular field (e.g. for the client to create dropdown values for filtering the data).