Dynamic Expressions LINQ Select - SelectMany from nested collection

c# dynamic-linq linq


Dynamic Expressions Docs

Taking this sample class structure into account -

public class Apprentice
    public Guid Id { get; set; }
    public string GivenName { get; set; }
    public string FamilyName { get; set; }
    public virtual ICollection<ApprenticeAddress> Addresses { get; set; }

public class ApprenticeAddress
    public Guid Id { get; set; }
    public Guid ApprenticeId { get; set; }
    public virtual Apprentice Apprentice { get; set; }
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string Town { get; set; }
    public Guid CountyId { get; set; }
    public virtual County County { get; set; }
    public string PostCode { get; set; }
    public bool IsPrimaryAddress { get; set; }
    public Guid AddressTypeId { get; set; }
    public virtual AddressType AddressType { get; set; }

Based upon the above documentation and sample class structure provided, I have been struggling to compile a dynamic selector for selecting random properties not known at runtime. The main problem I have been having is the selecting of say the AddressLine1 property of any Addresses linked to the returned Apprentice.

This example LINQ select will perform what I need to do but can anyone help transforming that into a data object initializer string?

var r = repo.GetAll().ToList().Select(x =>
            addresses = x.Addresses.SelectMany(y => y.AddressLine1)


If I use the following code and data object initializer string passed into the Select extension method, I get the anonymous object I desire -

var whereTxt = "Active";
var selectTxt = "new (GivenName AS GivenName,FamilyName AS FamilyName)";
var repo = Storage.DataContext.GetRepository<Apprentice>();
return repo.GetAll().Where(whereTxt).Select(selectTxt).AsQueryable();

The problem I am having, is determining the syntax of retrieving specific properties (not known at runtime) from nested collections

10/17/2018 3:07:19 PM

Accepted Answer

This can easily be done using System.Linq.Dynamic.Core :

var data = new[]
    new Apprentice { FamilyName = "f", Addresses = new [] { new ApprenticeAddress { AddressLine1 = "address x" }, new ApprenticeAddress { AddressLine1 = "address y" } } }

var result = data.Select(x => new { x.FamilyName, Addresses = x.Addresses.Select(y => y.AddressLine1) });
Console.WriteLine("result: " + JsonConvert.SerializeObject(result, Formatting.Indented));

var resultDynamic = data.Select("new (FamilyName as FamilyName, Addresses.Select(AddressLine1) as Addresses)");
Console.WriteLine("resultDynamic: " + JsonConvert.SerializeObject(resultDynamic, Formatting.Indented));

For a full working example see ConsoleApp2 in https://github.com/StefH/System.Linq.Dynamic.Core.TestApps

Note that Addresses.SelectMany(y => y.AddressLine1) is wrong, this selects the characters from the address.

10/21/2018 8:53:25 AM

Related Questions

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow