Flatten properties into List in EF Core

Viewed 93

Lets say I have an entity which can reference other rows in its table, defined like this:

MyEntity
{
    public string Id { get; set; }
    public string ParentId { get; set; }
    public bool isRelevant { get; set; }

    public virtual List<MyEntity> Children
}

Attempting something like:

var result = await MyEntities
                    .SelectMany(o => new List<string> { o.Id, o.ParentId })
                    .ToListAsync();

This however results in a runtime error:

The LINQ expression could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable'...

How can I select all of the MyEntity Id AND ParentId values as a single list without reverting to client-side evaluation?

To be clear, I would like the result from the database to be something like:

["Id1", "parentId1", "Id2", "ParentId2"]

2 Answers

I assume just the parents not the children

create class:

public class Parent{

public string Id {get;set;}
public string ParentId {get;set;}

}

then

var result = MyEntities.select(x => new Parent(){Id = x.Id, ParentId = x.ParentId}).toList();

edit:

To flatten to string list something like this, though you would run it against the ef resultset not directly against ef,

Though i cant think of any reason you would want to do that, this will do all the properties in the class, if i understood question this will do list of all values:

var properties = result.SelectMany(x => x.GetType().GetProperties().Select(y => y.GetValue(x))).ToList();

you would probaly need to tweak it, adding a where clause, to ignore the properties you dont want included as this one will do all the properties, also might need to add toString() to getValue

so in your case:

var properties = result.SelectMany(x => x.GetType().GetProperties().Where(i => i.Name == "Id" || i.Name == "ParentId").Select(y => y.GetValue(x))).ToList();

You cannot use List of String to store an anonymous value object.

Please use object or Parent class including id and parent id as properties.

My opinion is to use class called "Parent"

.Select(o => new { o.Id, o.ParentId })

or

.Select(o => new Parent { Id = o.Id, ParentId = o.ParentId })

Related