I'm using a modified version of LinqKit
in order to have my extensions at one place.
Therefore I have a singel part of each of my entity-classes where I define my expression, e.g. for tblMain
:
public partial class tblMain
{
public static Expression<Func<tblMain, bool>> IsVisible => (e) => e.MainStatus == "Visible";
}
In a query I am now able to write something like this
var visibleEntries = dbContext
.tblMain
.AsExpandable()
.Where(m => tblMain.IsVisible.Invoke(m))
.ToList();
which will return me all of the visible entries of the table tblMain
.
I wondered if there is any way to not have this a static property. This would enable me to use Interfaces
like IVisibilityEntity
to force a public IsVisible
property on specific types.
For now I've ended up with:
public Expression<Func<bool>> IsVisible2 => Expression.Lambda<Func<bool>>(Expression.Invoke(IsVisible, Expression.Variable(typeof(tblMain))));
but this throws me an exception
InvalidOperationException: variable 'm' of type 'tblMain' referenced from scope '', but it is not defined.
Same when using Expression.Constant(this, typeof(tblMain))
as second parameter.
What I would love to have is a query like
var visibleEntries = dbContext
.tblMain
.AsExpandable()
.Where(m => m.IsVisible.Invoke())
.ToList();
This may seem not that much of a change. But I really want to be able to use the interface-feature to describe my underlying database-model.
With interfaces it also allows checks, e.g. if(myEntity is IVisibilityEntity)
to do specific visibility-stuff.
Any ideas if this is possible and how this can be achieved?
Edit 1
As of the first comment. I use LinqKit
to enable the same logic for sub-queries:
var visibleEntries = dbContext
.tblMain
.AsExpandable()
.Where(m => tblMain.IsVisible.Invoke(m))
.Select(m => new
{
VisibleSubs = m.tblSub.Where(s => tblSub.IsVisible.Invoke(s)).Select(s => new
{
// ...
})
})
.ToList();
The query above would give me all visible main-entries and their related (and also visible) sub-entries. But this is not possible with simply writing m.tblSub.Where(tblSub.IsVisible)
as this shows
CS1929 'ICollection<tblSub>' does not contain a definition for 'Where' and the best extension method overload 'Queryable.Where<tblSub>(IQueryable<tblSub>, Expression<Func<tblSub, bool>>)' requires a receiver of type 'IQueryable<tblSub>'