I have taken my first dive into expressions as a way to reduce code duplication.
I have created 2 expression functions to isolate the work for 2 separate entities.
- Site
- SiteServer
public class CMSite
{
public int ID {get;set;}
public string Name {get;set;}
public ICollection<CMSiteServer> SiteServers { get; set; }
}
public class CMSiteServer
{
public int ID {get;set;}
public string Name {get;set;}
public int SiteID {get;set;}
[ForeignKey("CMSite")]
public decimal SiteID { get; set; }
public CMSite Site {get;set;}
}
The relationship is 1 site = multiple site servers
Each site and server has a series of properties and i've created various filter objects to permit searching these enties.
Use case:
- Search sites containing servers with property x
- search servers containing sites with property x
My code contains the following methods:
public static Expression<Func<CMSiteServer, bool>> GetServerExpression(CMSiteServerFilter filter, bool Active) {
...
}
public static Expression<Func<CMSite, bool>> GetSiteExpression(CMSiteFilter filter, bool Active) {
...
}
I can solve use case 1 with this method:
public static IQueryable<CMSite> ApplyQueryFilterServer(this IQueryable<CMSite> qry, CMSiteServerFilter filter, bool Active)
{
if (filter == null)
return qry;
var exp = GetServerExpression(filter, Active);
qry = qry.Where((s) => s.CMSiteServers.AsQueryable().Any(exp));
return qry;
}
However, i can't find an equivalent for use case 2.
public static IQueryable<CMSite> ApplyQueryFilterSite(this IQueryable<CMSiteServer> qry, CMSiteFilter filter, bool Active)
{
if (filter == null)
return qry;
var exp = GetServerExpression(filter, Active);
// this is the piece that won't work:
qry = qry.Where((s) => s.CMSite.AsQueryable().Any(exp));
return qry;
}
because Server.CMSite is singular the "AsQueryable" won't work
i'm trying to avoid defining all my filter criteria once for each IQueryable source element.