how do I chain this ( list of course of category "2sexycontent" )

May 26, 2014 at 3:54 PM
Edited May 26, 2014 at 3:54 PM
In the access related data demos there is the example to show a list of all categories and then the courses in that category

I have a use-case where i need to make a list of all the courses of a specific category

of course i can use that example and then do an if check in the loop if the category name is "2sexycontent" and only then show the courses but im sure this can be done better with the chained filters

how would I create a dataset with just the courses where the category name = "2sexycontent"

thanks in advance for any help
Coordinator
May 27, 2014 at 10:20 PM
Edited May 27, 2014 at 10:20 PM
Hi chinablue

I'm assuming you have multiple categories assigned - and that you're using entities for categories.

The nicest way would be if the DataSource<ValueFilter>() would allow this. Unfortunately it doesn't do this yet - as it's a bit tricky since it would have to know which value to compare to with related entities. It also doesn't allow "partial" detection yet either (a contains-query).

So you have 2 options:
  1. if you start with all courses, use a simple LINQ statement like
foreach(var x in AsDynamic(Data["Courses"]).Where(x => x.Categories......))
{
...
}
  1. or you can start with the entity containing the category, and then getting all assigned items like
    // all parents, no matter what entity-type
    var cat = AsEntity(Content.Category[0]);
    var questions = (cat as ToSic.Eav.IEntity).Relationships.AllParents
        .Where(q => q.Type.Name == "QandA");
Did that help?
Coordinator
May 27, 2014 at 10:38 PM
I created a little demo for you here.

It will be part of a flexible FAQ App and it shows the second use case. The app isn't done yet, but I'll package/distribute it in about a week.
May 28, 2014 at 8:15 AM
I will check it out and try what works best for me, thanks you

talking about apps.

I posted a question a while earlier and you mentioned a sample app for that as well,


https://sexycontent.codeplex.com/discussions/544577

did you forget about that one, still would like to know the best way to do this specific use.
May 10, 2016 at 1:30 AM
Hello, I'm following up on the original topic of this post. I similarly have created categories and I want to filter entities by category. Entities can be in multiple categories. Currently, my query is returning items that only have this category. It's not returning the instances that have that category and an additional category.

Is there a way to do this in the visual query? If I have to use the LINQ statement, that would go in the template file, correct?
Coordinator
May 10, 2016 at 12:08 PM
the LINQ way is certainly the one that works for sure. I don't know about the visual query but if you tried it, then it's probably correct.

As of now, the filter can only do "=" and neither "contains", "<" ">" or "<=" etc.
May 10, 2016 at 8:25 PM
Okay, I'm trying the LINQ statement, and I think I need help in writing it. I can't quite get it to work. This is the statement I'm using:
    @foreach(var cont in AsDynamic(Data["Default"]).Where( cont => cont.categories.EntityId.Contains("1299"))) {}
The error message I get is "There was an error while rendering the template: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'System.Collections.Generic.List<ToSic.SexyContent.DynamicEntity>' does not contain a definition for 'EntityId' at CallSite.Target(Closure , CallSite , Object )"

I can't figure out how to use "Where" and "Contains" to select for the ID of the category I want to filter by. Any pointers here? As you can probably tell, I am new to C#.

Note that the following statement works just fine in returning all entities:
@foreach(var cont in AsDynamic(Data["Default"]) {}
Coordinator
May 19, 2016 at 2:39 PM
Just a guess - but you probably need to change it a bit like
 var filtered = AsDynamic(Data["Default"]).Where( cont => cont.categories.Any( cat => cat.EntityId == "1299" ));

 @foreach(var f in filtered) {

}
May 24, 2016 at 12:00 AM
Thanks, but I am now getting this in the error messages:
"Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type"
Coordinator
May 24, 2016 at 4:51 PM
Try casting it to a IEnumerable<dynamic> - that should probably do the trick - a bit like this:
 var filtered = (AsDynamic(Data["Default"])  as IEnumerable<dynamic>).Where( cont => cont.categories.Any( cat => cat.EntityId == "1299" ));

 @foreach(var f in filtered) {

}
This above is just dummycode, untested. But here's a LINQ which I'm using just now (so this LINQ works, even though it does something else than you need):
    @{
        var groupedPractices = (AsDynamic(Content.Practices) as IEnumerable<dynamic>)
                            .OrderBy(p => p.RecommendationStatus[0].Priority)
                            .GroupBy(p => p.RecommendationStatus[0].EntityId)
                            .ToList();
    }
    @foreach(var pset in groupedPractices) {
            var recStatus = pset.First().RecommendationStatus[0];
            <h3>@recStatus.Name</h3>
            <ol>
            @foreach(dynamic practice in AsDynamic(pset)) {
                <li class="sc-element"><a href="@practice.Link" target="_blank">@practice.Title</a>@practice.Toolbar<br>
                    @Html.Raw(practice.Recommendation)
                </li>
            }
        </ol>
        
    }
May 24, 2016 at 7:38 PM
Thanks, I am still getting the lambda expression error, but I found another way to do this using relationships (as demoed here: http://2sxc.org/dnn-app-demos/en/Apps/FAQ-with-Categories).

Thanks for your help.