Nested Relational Queries

Autofilter supports related entities querying at version 1.1.0 and above. You can filter your One-to-Many, Many-To-Many or One-To-One related entities with nested FilterBase objects.

Let's make a sample.

Over Collections

  • Entity class anatomy:
pulic class Blog
{
    public string BlogId { get; set; }
    public int CategoryId { get; set; }
    public string Title { get; set; } 
    public virtual ICollection<Comment> Comments { get; set; } // We'll work on this field
}
pulic class Comment
{
    public string CommentId { get; set; }
    public string BlogId { get; set; }
    public string Language { get; set; }
    public string Message { get; set; } 
    public virtual Blog Blog { get; set; }
}
  • Let's create a dto to filter by Language property.

pulic class BlogFilterDto : FilterBase
{
    public int? CategoryId { get; set; }
    public string Title { get; set; } 
    public CommentFilterDto Comments { get; set; } // Be careful, it's not a collection and same name with entity.
}
pulic class CommentFilterDto : FilterBase
{
    public string Language { get; set; }
    [StringFilterOptions(StringFilterOption.Contains)]
    public string Message { get; set; }
}
  • Just apply filter to Blogs:
pulic ActionResult Index([FromQuery]BlogFilterDto filter)
{
	using(var db = new MyDbContext())
	{
	    var data = db.Blogs.ApplyFilter(filter).Tolist();
	    return View(data)
	}
}
  • You can send following requests to check result. No any include required for filtering! That's awesome!
QueryString Generated LINQ
?Comments.Language=en db.Blogs.Where(x => x.Comments.Any(a => a.Language == "en"))
?comments.language=en&message=awesome db.Blogs.Where(x => x.Message.Contains("awesome") && x.Comments.Any(a => a.Language == "en"))

Over Objects

  • Entity class anatomy:
pulic class Blog
{
    public string BlogId { get; set; }
    public int CategoryId { get; set; }
    public string Title { get; set; } 
    public virtual Author Author { get; set; } // We'll work on this field
}
pulic class Author
{
    public string AuthorId{ get; set; }
    public string BlogId { get; set; }
    public DateTime RegisterDate { get; set; }
    public string FullName{ get; set; }
    public bool IsPremium { get; set; }
    public virtual Blog Blog { get; set; }
}
  • Let's create a dto to filter by Language property.
pulic class BlogFilterDto : FilterBase
{
    public int? CategoryId { get; set; }
    public string Title { get; set; } 
    public AuthorFilterDto Comments { get; set; } // Be careful, it's not a collection and same name with entity.
}
pulic class AuthorFilterDto : FilterBase
{
    public bool? IsPremium { get; set; }
    [StringFilterOptions(StringFilterOption.Contains)]
    public string FullName { get; set; }
}
  • Then you can send following requests to check result. No any include required for filtering! That's awesome!
QueryString Generated LINQ
?author.isPremium=True db.Blogs.Where(x => x.Author.IsPremium == true
?author.isPremium=False&author.fullName=John db.Blogs.Where(x => x.Author.IsPremium == false && x.Author.FullName.Contains("John")
In this document