How to expand sub levels of childs with AutoMapper and OData?

asp.net automapper c# entity-framework-6 odata

Accepted Answer

I do this by using the fact that.ProjectTo provides anIQueryable So, instead of calling, I let the OData framework handle queries.ToListAsync() nonetheless, restoring theIQueryable .

// In some class that is ': ODataController'
[EnableQuery] //Attribute makes sure the OData framework handles querying
public IQueryable<TDto> Get(ODataQueryOptions<TDto> options) {
    //The names of the properties requested by the client in the '$expand=' query option
    string[] requestedExpands = Helpers.Expand.GetMembersToExpandNames(options); // I made a helper for this, you can probably just use your code, or see my impementation below.

    var set = Db.Set<TEntity>().AsNoTracking(); //You might want to remove AsNoTracking if it doesn't work
    var converted = set.ProjectTo<TDto>(MapConfig, null, requestedExpands);
    return converted;
}

In this instanceTDto is the kind of thing I want to send the customer.TEntity is the POCO class for Entity Framework.

My MapConfig I configured expandable properties to be in the "Explicit expand" mode on application startup:

MapConfig = new MapperConfiguration(cfg => {
    cfg.CreateMap<EFType, DTOType>(MemberList.Destination)
        .ForMember(c => c.ExpandableProperty, options => options.ExplicitExpansion());
});

I want for the data by nesting, as I said in comments.$expand= the URL:

api/myEntity?$expand=myChildElement($expan‌​d=mySubChildElement)

I hope you can have the same success I had with this.

EDIT: If you wish to elaborate, I once again examined it.myEntity.myChildElement.mySubChildElement the string[] You must pass AutoMapper'requestedExpands' with a single entry:myChildElement.mySubChildElement . In addition, I have developed a mapping for each of the threeExplicitExpansion option.


update on my use of as per @Tim Pohlmann's requestGetMembersToExpandNames :

public static class Expand {

    public static string[] GetMembersToExpandNames(ODataQueryOptions options) {
        return GetExpandPropertyPaths(GetExpandItems(options?.SelectExpand?.SelectExpandClause)).ToArray();
    }

    private static IEnumerable<string> GetExpandPropertyPaths(IEnumerable<ExpandedNavigationSelectItem> items, string prefix = "") {
        foreach(var item in items) {
            foreach(var res in GetExpandPropertyPaths(item, prefix)) {
                yield return res;
            }
        }
    }

    private static IEnumerable<string> GetExpandPropertyPaths(ExpandedNavigationSelectItem item, string prefix = "") {
        var curPropName = item.NavigationSource.Name;
        var nestedExpand = GetExpandItems(item.SelectAndExpand).ToArray();
        if(nestedExpand.Count() > 0) {
            foreach(var res in GetExpandPropertyPaths(nestedExpand, $"{prefix}{curPropName}.")) {
                yield return res;
            }
        } else {
            yield return $"{prefix}{curPropName}";
        }
    }

    private static IEnumerable<ExpandedNavigationSelectItem> GetExpandItems(SelectExpandClause sec) {
        if(sec != null) {
            var res = sec?.SelectedItems?.OfType<ExpandedNavigationSelectItem>();
            if(res != null) {
                return res;
            }
        }
        return new ExpandedNavigationSelectItem[0];
    }
}
3
9/12/2018 9:40:32 AM


Related Questions





Related

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