Git Product home page Git Product logo

entityframework.dynamicfilters's People

Contributors

cosminvlad avatar jaenyph avatar jcachat avatar jonathanmagnan avatar lempireqc avatar ronaldme avatar stgelaisalex avatar tobiasmarklund avatar waqasm78 avatar winwink avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

entityframework.dynamicfilters's Issues

Does not support TPT Inheritance

Before i get to my problem, i want to say thank you for the grate work you are doing on this project. We really appreciate all the effort. :)

The problem i'm experiencing is that i have implemented the Table Per Type Inheritance and i have a simplified model below.

public interface IEntity
{
bool IsDeleted { get; set; }
}

public class Person : IEntity
{
public int id { get; set; }
public bool IsDeleted { get; set; }
}

public class Instructor : Person
{
public DateTime HireDate { get; set; }
}

public class Student : Person
{
public DateTime EnrollmentDate { get; set; }
}

public class FilterDbContext : DbContext
{
public FilterDbContext()
{
this.EnableAllFilters();
}

    public DbSet<Person> People { get; set; }
    public DbSet<Instructor> Instructors { get; set; }
    public DbSet<Student> Students { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>().ToTable("People");
        modelBuilder.Entity<Instructor>().ToTable("Instructors");
        modelBuilder.Entity<Student>().ToTable("Students");

       modelBuilder.Filter("IsDeleted", (IEntity e) => e.IsDeleted, false);
    }

}

private static void Main(string[] args)
{
var context = new FilterDbContext();
var instructors = context.Instructors.ToList();
}

model

I want to get all instructors where isDeleted = false. but as you can see, the isDeleted property is on the Person Model and the Instructor model inherits from Person. However on the Database, person is its on table and Instructor is also its on table with its primary key being a foreign key to the person table.

Oracle support

Hello guys,

Does anyone know if DynamicFilters is fully compatible with Oracle ?

I can run my code with SQL Server; but when I use Oracle; i have few errors.

Thanks for your help !

Running Seed method.
System.Data.Entity.Core.EntityCommandCompilationException: An error occurred while preparing the command definition. See the inner exception for details. ---> System.ArgumentException: DbComparisonExpression requires arguments with comparable types.
at System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder.DbExpressionBuilder.CreateComparison(DbExpressionKind kind, DbExpression left, DbExpression right)
at System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder.DbExpressionBuilder.Equal(DbExpression left, DbExpression right)
at EntityFramework.DynamicFilters.DynamicFilterQueryVisitor.BuildFilterExpressionWithDynamicFilters(String entityName, IEnumerable1 filterList, DbExpressionBinding binding, DbExpression predicate) at EntityFramework.DynamicFilters.DynamicFilterQueryVisitor.Visit(DbScanExpression expression) at System.Data.Entity.Core.Common.CommandTrees.DbScanExpression.Accept[TResultType](DbExpressionVisitor1 visitor)
at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitGroupExpressionBinding(DbGroupExpressionBinding binding)
at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbGroupByExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbGroupByExpression.Accept[TResultType](DbExpressionVisitor1 visitor) at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression) at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBinding(DbExpressionBinding binding) at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBindingEnterScope(DbExpressionBinding binding) at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbProjectExpression expression) at System.Data.Entity.Core.Common.CommandTrees.DbProjectExpression.Accept[TResultType](DbExpressionVisitor1 visitor)
at EntityFramework.DynamicFilters.DynamicFilterInterceptor.TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
at System.Data.Entity.Infrastructure.Interception.DbCommandTreeDispatcher.b__0(IDbCommandTreeInterceptor i, DbCommandTreeInterceptionContext c)
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher1.Dispatch[TInterceptionContext,TResult](TResult result, TInterceptionContext interceptionContext, Action2 intercept)
at System.Data.Entity.Infrastructure.Interception.DbCommandTreeDispatcher.Created(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)
--- End of inner exception stack trace ---
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)
at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContext context, DbQueryCommandTree tree)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Boolean streaming, Span span, IEnumerable1 compiledQueryParameters, AliasGenerator aliasGenerator) at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery1.<>c__DisplayClass7.<GetResults>b__6() at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery1.<>c__DisplayClass7.<GetResults>b__5() at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery1.GetResults(Nullable1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0() at System.Data.Entity.Internal.LazyEnumerator1.MoveNext()
at System.Linq.Enumerable.Single[TSource](IEnumerable1 source) at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__3[TResult](IEnumerable1 sequence)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable1 query, Expression queryRoot) at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression) at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression) at System.Linq.Queryable.Count[TSource](IQueryable1 source)

Filter not wrapping other criteria

Good Evening,

When using Asp.net Identity, and applying filters for tenant and active, the finduserbyid method generates SQL like this:
SELECT
Extent1.UserID,
Extent1.CompanyID,
Extent1.AuthorizedPhone,
Extent1.AuthorizedEmail,
Extent1.Username,
Extent1.Password,
Extent1.Active,
Extent1.EmailConfirmed,
Extent1.SecurityStamp,
Extent1.PhoneNumberConfirmed,
Extent1.TwoFactorEnabled,
Extent1.LockoutEndDateUtc,
Extent1.LockoutEnabled,
Extent1.AccessFailedCount,
Extent1.OfflineDataKey,
Extent1.ZoneCalcRepID,
Extent1.Created,
Extent1.CreatedBy,
Extent1.Edited,
Extent1.EditedBy
FROM Users AS Extent1
WHERE (Extent1.Username = @p__linq__0) OR ((Extent1.Username IS NULL) AND (@p__linq__0 IS NULL)) AND ((Extent1.CompanyID = @DynamicFilterParam_CompanyFilter_CompanyID) OR (@DynamicFilterParam_CompanyFilter_CompanyID IS NULL)) AND ((Extent1.Active = @DynamicFilterParam_IsActive_Active) OR (@DynamicFilterParam_IsActive_Active IS NULL)) LIMIT 2

It appears the where clause generated by the method isn't wrapped in () before the filter is applied, as such I am getting back results I shouldn't due to the "or"

I am going to start looking at the source tomorrow, but was hoping this might be a quick fix for you, as the only other filtering option I found caches parameters and won't allow me to dynamically change filters.

Thanks!

Steve

List() parameter - NullReference

Hello,
I've tried to define filter with Contains() operator just like in your example.
This is what I have defined:

var values = new List<int> { 1, 2, 3, 4, 5 };
var values2 = new List<int?> { null, 1, 2, 3, 4, 5 };
modelBuilder.Filter(DataFilters.MustHavePlace, (IMustHavePlace p, List<int> placeList) => placeList.Contains(p.PlaceId), () => values);
modelBuilder.Filter(DataFilters.MayHavePlace, (IMayHavePlace p, List<int?> placeList) => placeList.Contains(p.PlaceId), () => values2);

If I'll call the query for the specified entity it will always return the following exception

System.NullReferenceException: Object reference not set to an instance of an object.
at EntityFramework.DynamicFilters.DynamicFilterExtensions.SetSqlParameters(DbContext context, DbCommand command)
at EntityFramework.DynamicFilters.DynamicFilterCommandInterceptor.SetDynamicFilterParameterValues(DbCommand command, DbContext context)
at EntityFramework.DynamicFilters.DynamicFilterCommandInterceptor.ReaderExecuting(DbCommand command, DbCommandInterceptionContext`1 interceptionContext)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__d(IDbCommandInterceptor i, DbCommand t, DbCommandInterceptionContext`1 c)
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__6()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__3[TResult](IEnumerable`1 sequence)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression)

"Contains" doesn't work with SQL CE

Just for your information - filters with a collection of parameter values doesn't work with SQL CE. The issue is related to SqlCeMultiCommand, which Entity Framework creates for executing requests to SQL CE database. This class overrides CommandText { set; } so it just raises NotSupportedException. Actual command text is located in CommandTexts property, which is an array of strings. Unfortunately, SqlCeMultiCommand is internal, so there is no way to access CommandTexts property without reflection. So I don't know how to fix it...

Filters for insert/update

I think i might have answered my question when i typed filters into the title, however I basically want to be able to control CRUD operations with separate filters for each operation type, is this something you are doing or it already does, or perhaps have I missed the point?

Sign assembly

Hi. It would be nice if the dll would have a strong name.

What LINQ methods do NOT work (SQL Server)

Hello,

Great tool - thank you for this! I'm using this to filter data by UserId (INT) as our SQL SERVER 2014 database supports multi-user, each table has a UserId column (and a second primary key column as well). I had a little issue yesterday where I believe using the LINQ Find() extension where I removed the check for UserId and just checking for the secondary key failed. For example I used to use entity.Find(userId, entityId) and since applying the DynamicFilters I figured the userId part was no longer needed. I believe this is the cause of my error in that the Find() method still needs both primary keys in the composite key?

If there is a list of info on when dynamic filters can work vs. when they cannot be applied I'd appreciate it so I don't expect that it's filtering for me when in fact it's not.

Thank you

bitwise AND in dynamic filter not recognized by Expression Visitor

I tried to create a global filter on my context where users can be assigned to any of a number of dynamic "partitions". Their partition key is compared to an entity's partition key if it is a partitioned item (think like a Customer can be a partition, and a customer's project can be a partition, and users can be constrained within any level of depth within these partitions)

The syntax:

mb.Filter("FilterPartition",
(IPartitioned item, int? userPartitionKey) => (!userPartitionKey.HasValue || ((userPartitionKey.Value & item.PartitionKey) == userPartitionKey.Value)),
() => CurrentPartitionKey)

When I go to Update-Database i get this error:

"Unhandled NodeType of And in LambdaToDbExpressionVisitor.VisitBinary"

How-to: Exclude call from UserManager (asp.net.Identity)

Hi,

I changed EntityFramework.Filters with yours. I am now facing an issue.

I used the plugin for multi-tenancy.

I have a ITenantable interface, wich ApplicationUser implement (and some other model).
I've set the filter on this interface
modelBuilder.Filter("Tenant", (ITenantable e) => e.TenantId, TenantHelper.GetCurrentTenantId());

Now when i try to login, the filter prevent the query from finding my user as GetCurrentTenantId return null as no user is logged yet. I need to find a way to stop the filter for some specific query?

I guess it used to work with ef.Filters as the interceptor wasnt ran when query was coming from UserManager?

Thank you

Supporting Any() in Linq filters

I'm trying to create a global filter like so

modelBuilder.Filter("GroupFilter", (IGroupableEntity e, IEnumerable<int> groups) => e.Groups.Any(g => groups.Contains(g)), new int[0]);

Where the interface looks like so...

public interface IGroupableEntity
    {
        IEnumerable<int> Groups { get; }
    }

The theory being that an entity can be assigned to groups and for a user to view that entity the user must be a member of those groups.

However the above doesn't work. With the error Property SGroups not found in Entity Type IGroupableEntity

Would Any() be supported in a query like this?

Does not support TPH inheritance

First of all - thanks very much @jcachat for your work on this! I'm hoping we may finally have a solution to this much needed EF feature.

The issue I'm experiencing is as per this one.

Exception:
Annotation 'DynamicFilter_Flagged' value 'EntityFramework.DynamicFilters.DynamicFilterDefinition' conflicts with value 'EntityFramework.DynamicFilters.DynamicFilterDefinition' for table 'Entity'. Annotations of a given name configured for a given table must be specified only once or have have matching values in each configuration.

Simple sample code:

internal class Program
{
    private static void Main(string[] args)
    {
        using (var ctx = new TestDbContext())
        {
            ctx.Entities.Add(new Entity {Name = "test"});
            ctx.SaveChanges();
        }

        Console.Write("Press any key to exit.");
        Console.ReadKey();
    }
}

public class Entity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool Flag { get; set; }
}

public class DervivedEntity : Entity
{
}

public class TestDbContext : DbContext
{
    public DbSet<Entity> Entities { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Filter("Flagged", (Entity e) => e.Flag, true);
        this.InitializeDynamicFilters();
    }
}

Filter not working correctly when two navigation properties have the same type.

Hi,

I have noticed that when an entity has two navigation properties of the same type, then the filter is only applied on the first navigation property.
A similar thing happens if a navigation property has the same type as the parent. Then the navigation property isn't filtered either.

Here is an example:
C# Console Application with the following NuGet packages:
EntityFramework version="6.1.2"
EntityFramework.DynamicFilters version="1.3.5.1"

Expected result:
The navigation properties (Nav1, Nav2, Nav3) are all null because they have IsDeleted = true.
Actual result:
Only Nav1 is null.

using System;
using System.Data.Entity;
using System.Linq;
using EntityFramework.DynamicFilters;

namespace DynamicFilters
{
    class Program
    {
        static void Main()
        {
            var context = new Context();

            // Seed the entity.
            context.Entities.Add(new EntityA
            {
                IsDeleted = false,
                Nav1 = new EntityB
                {
                    IsDeleted = true
                },
                Nav2 = new EntityB
                {
                    IsDeleted = true
                },
                Nav3 = new EntityA
                {
                    IsDeleted = true
                }
            });
            context.SaveChanges();

            // Create a new context in order to have a clear change tracker.
            context.Dispose();
            context = new Context();

            // Get entity.
            var entity = context.Entities
                .Include(e => e.Nav1)
                .Include(e => e.Nav2)
                .Include(e => e.Nav3)
                .First();

            Console.WriteLine("Nav1: {0}\nNav2: {1}\nNav3: {2}", entity.Nav1, entity.Nav2, entity.Nav3);

            // Wait
            Console.WriteLine("End. Press key...");
            Console.ReadKey();
        }
    }

    class Context : DbContext
    {
        public IDbSet<EntityA> Entities { get; set; }

        static Context()
        {
            Database.SetInitializer(new DropCreateDatabaseAlways<Context>());
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Filter("SoftDelete",
                (ISoftDelete entity) => entity.IsDeleted,
                false);

            base.OnModelCreating(modelBuilder);
        }
    }

    interface ISoftDelete
    {
        bool IsDeleted { get; set; }
    }

    class EntityA : ISoftDelete
    {
        public int Id { get; set; }
        public bool IsDeleted { get; set; }
        public EntityB Nav1 { get; set; }
        public EntityB Nav2 { get; set; }
        public EntityA Nav3 { get; set; }
    }

    class EntityB : ISoftDelete
    {
        public int Id { get; set; }
        public bool IsDeleted { get; set; }
    }
}

Feature request: DisableAllFilters()

Hi,

It would be nice it there was an extension to disable all filters at once without having to specify every filter explicitly.
I noticed a problem in my project, where the seed method produced duplicate entries because the DbContext.AddOrUpdate() method did an insert instead of an update since the entity was filtered out.
I now disable all filters separately in the seed method, but this has to be adjusted every time a filter gets added or removed.

By the way: The assembly version is still at version 1.3.4 while the nuget package is at 1.3.6

Is possible for your tool to cover a such scenario ?

Hello !
I want to know how is possible to do with your tool , the below scenario :
Article - has 2 child entities F1 and F2.

I want to construct the query step by step depending from some condition , and at the end I want to get data from database using Tolist.

Dim mylist as iQuerable(Of Article)

Mylist=Context.Set(Of Article)

If condition1 then ...."From Mylist filter the articles with ".vl1=1 ..." End if

If Condition2 then ..."From Mylist filter the articles with ".id>=5 ..." End if

If Condition3 then ....For all the articles in MyList , include the items on child F1 that have ".quantity>3".... End if

If condition4 then ....For all the articles in MyList , from the items on child F1 that are included from the previous condition3 , include only those that have ".value5=0.... end if

If condition5 then ....For all the Articles in MyList , include the items from child F2 that have .type=3....." End if

MyList.Tolist

How is possible to create this ? A solution would be very helpful.

Thank you !

NullReferenceException on querying for null dates

Configured like this:

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Filter("IsSubscribed", (Subscription subscription) => (subscription.End == null));
        }

        public static ApplicationDbContext Create()
        {
            ApplicationDbContext ctx = new ApplicationDbContext();
            ctx.DisableAllFilters();
            return ctx;
        }

Using like this:

    public class User
    {
        public User(ApplicationDbContext db)
        {
            _db = db;
        }
        public async Task<Contact> GetUser(int id)
        {
            _db.EnableFilter("IsSubscribed");
            return await _db.Contacts
                .Where(c => c.Id == id)
                .Include(c => c.User.Subscriptions)
                .SingleAsync();
        }
    }

Gets me this View fiddle, click 'result':

NullReferenceException
Object reference not set to an instance of an object.
MessageObject reference not set to an instance of an object.
Data
(0 items)
InnerException_null_
TargetSite
RuntimeMethodInfo
LambdaToDbExpressionVisitor.VisitMember (MemberExpression node)
NameVisitMember
DeclaringType
typeof(LambdaToDbExpressionVisitor)
ReflectedType
typeof(LambdaToDbExpressionVisitor)
CustomAttributes
(0 items)
MetadataToken100663385
Module
Module
MethodImplementationFlagsIL
MethodHandle
RuntimeMethodHandle
System.RuntimeMethodHandle
Value
IntPtr
10996888
AttributesPrivateScope, Family, Virtual, HideBySig
CallingConventionStandard, HasThis
IsGenericMethodDefinitionFalse
ContainsGenericParametersFalse
IsGenericMethodFalse
IsSecurityCriticalTrue
IsSecuritySafeCriticalTrue
IsSecurityTransparentFalse
IsPublicFalse
IsPrivateFalse
IsFamilyTrue
IsAssemblyFalse
IsFamilyAndAssemblyFalse
IsFamilyOrAssemblyFalse
IsStaticFalse
IsFinalFalse
IsVirtualTrue
IsHideBySigTrue
IsAbstractFalse
IsSpecialNameFalse
IsConstructorFalse
MemberTypeMethod
ReturnType
typeof(Expression)
ReturnParameter
RuntimeParameterInfo
System.Linq.Expressions.Expression
ParameterType
typeof(Expression)
Name_null_
HasDefaultValueTrue
DefaultValue_null_
RawDefaultValue_null_
Position-1
AttributesNone
Member
RuntimeMethodInfo
LambdaToDbExpressionVisitor.VisitMember (MemberExpression node)
IsInFalse
IsOutFalse
IsLcidFalse
IsRetvalFalse
IsOptionalFalse
MetadataToken134217728
CustomAttributes
(0 items)
ReturnTypeCustomAttributes
RuntimeParameterInfo
System.Linq.Expressions.Expression
ParameterType
typeof(Expression)
Name_null_
HasDefaultValueTrue
DefaultValue_null_
RawDefaultValue_null_
Position-1
AttributesNone
Member
RuntimeMethodInfo
LambdaToDbExpressionVisitor.VisitMember (MemberExpression node)
IsInFalse
IsOutFalse
IsLcidFalse
IsRetvalFalse
IsOptionalFalse
MetadataToken134217728
CustomAttributes
(0 items)
StackTraceย ย  at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitMember(MemberExpression node) ย ย  at System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor) ย ย  at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) ย ย  at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node) ย ย  at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitUnary(UnaryExpression node) ย ย  at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor) ย ย  at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) ย ย  at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node) ย ย  at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitBinary(BinaryExpression node) ย ย  at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor) ย ย  at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) ย ย  at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node) ย ย  at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitBinary(BinaryExpression node) ย ย  at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor) ย ย  at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) ย ย  at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node) ย ย  at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor) ย ย  at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) ย ย  at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.Convert(DynamicFilterDefinition filter, DbExpressionBinding binding, ObjectContext objectContext) ย ย  at EntityFramework.DynamicFilters.DynamicFilterQueryVisitor.BuildFilterExpressionWithDynamicFilters(String entityName, IEnumerable`1 filterList, DbExpressionBinding binding, DbExpression predicate) ย ย  at EntityFramework.DynamicFilters.DynamicFilterQueryVisitor.Visit(DbScanExpression expression) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DbScanExpression.Accept[TResultType](DbExpressionVisitor`1 visitor) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBinding(DbExpressionBinding binding) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbJoinExpression expression) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DbJoinExpression.Accept[TResultType](DbExpressionVisitor`1 visitor) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBinding(DbExpressionBinding binding) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbJoinExpression expression) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DbJoinExpression.Accept[TResultType](DbExpressionVisitor`1 visitor) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBinding(DbExpressionBinding binding) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBindingEnterScope(DbExpressionBinding binding) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbFilterExpression expression) ย ย  at EntityFramework.DynamicFilters.DynamicFilterQueryVisitor.Visit(DbFilterExpression expression) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DbFilterExpression.Accept[TResultType](DbExpressionVisitor`1 visitor) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBinding(DbExpressionBinding binding) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBindingEnterScope(DbExpressionBinding binding) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbProjectExpression expression) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DbProjectExpression.Accept[TResultType](DbExpressionVisitor`1 visitor) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBinding(DbExpressionBinding binding) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBindingEnterScope(DbExpressionBinding binding) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbSortExpression expression) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DbSortExpression.Accept[TResultType](DbExpressionVisitor`1 visitor) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBinding(DbExpressionBinding binding) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBindingEnterScope(DbExpressionBinding binding) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbProjectExpression expression) ย ย  at System.Data.Entity.Core.Common.CommandTrees.DbProjectExpression.Accept[TResultType](DbExpressionVisitor`1 visitor) ย ย  at EntityFramework.DynamicFilters.DynamicFilterInterceptor.TreeCreated(DbCommandTreeInterceptionContext interceptionContext) ย ย  at System.Data.Entity.Infrastructure.Interception.DbCommandTreeDispatcher.b__0(IDbCommandTreeInterceptor i, DbCommandTreeInterceptionContext c) ย ย  at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TInterceptionContext,TResult](TResult result, TInterceptionContext interceptionContext, Action`2 intercept) ย ย  at System.Data.Entity.Infrastructure.Interception.DbCommandTreeDispatcher.Created(DbCommandTree commandTree, DbInterceptionContext interceptionContext) ย ย  at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext) ย ย  at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory) ย ย  at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext) ย ย  at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext) ย ย  at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContext context, DbQueryCommandTree tree) ย ย  at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Boolean streaming, Span span, IEnumerable`1 compiledQueryParameters, AliasGenerator aliasGenerator) ย ย  at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption) ย ย  at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.b__6() ย ย  at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) ย ย  at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.b__5() ย ย  at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func`1 operation) ย ย  at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) ย ย  at System.Data.Entity.Core.Objects.ObjectQuery`1..GetEnumerator>b__0() ย ย  at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext() ย ย  at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) ย ย  at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
HelpLink_null_
SourceEntityFramework.DynamicFilters
HResult-2147467261

Can I dynamically provide the primary key column as the filtered property?

Really cool project!

I'm working on an authorization app and I would love to use these filters to do row level security. In your examples, you show how you can use a delegate/func to provide a list of values to filter against. Do you think this approach can also provide the primary key column as the filtered property? Assume each entity has only one primary key of type int.

It would be cool to not need to create filters for every entity whose rows I want to secure. I was thinking this may be possible by implementing a function that returns the primary key value for the entity, but I'm not sure. The filter below my help you understand what I'm trying to achieve.

modelBuilder.Filter("FilterByPK", (IFilterByPrimaryKey m, List valueList) => valueList.Contains( GetAuthorizedPrimaryKeyValues(m) ),true);

[Feature Request] Force db initializing on set filter

I have build a Filter class:

public class DisableFilter : IDisposable
{
    private string _filterName;
    private DbContext _context;

    public DisableFilter(string filterName, DbContext context)
    {
        _filterName = filterName;
        _context = context;
        _context.DisableFilter(_filterName);
    }

    #region IDisposable Members

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            _context.EnableFilter(_filterName);
        }
    }

    #endregion
}

To disable filters for a specified task:

using (var filter = FilterManager.DisableFilter(FilterManager.GlobalCompanyFilter))
{
   // query
}

but I have to ensure that the db is already initialized or an exception will be thrown. Maybe you can check the db status before setting a filter internally and initialize the db first?

DbContext.DisableFilter is not working

Hi,

This is my code to create and use a DbContext.

using (var context = new MyDbContext(GetConnectionString("DbConnection")))
{
    context.DisableFilter("CurrentCustomerFilter");
    //...
}

DisableFilter method throws exception: Filter name CurrentCustomerFilter not found.

I'm defining filter in the MyDbContext.OnModelCreating as like below:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
   modelBuilder.Filter("CurrentCustomerFilter", (IMustHaveCustomer c) => c.CustomerId, () => AbpSession.TenantId.Value);
}

When I debug, I see that OnModelCreating is not called when I create first MyDbContext instance. It's called when I try to run a query. So, DynamicFilters library can not find the filter since OnModelCreating is not called yet.

How can I solve this problem?

Filter by NavigationProperty

Hi John,

I had another idea (need) here. I need a condition for NavigationProperty, must reach a certain field in a parent table is equal "NNNNN" as in the example below:

modelBuilder.Filter(GetType().Name, (Menu query, List values) =>
query.IdTipoMenu == 0 ||
query.Descricao == "XXX - SETRIN" ||
query.MenuSuperior.Descricao == "XXX - SETRIN" ||
values.Contains(query.IdMenu),
() =>
{
if (FilteredValues().Get(GetType().Name) == null)
{
var modulosDisponiveis = new Repositorio().ObjectSet.Where(t => t.Disponivel).Select(t => t.IdModulo).ToList();
var modulos = new Repositorio().ObjectSet.Where(m => modulosDisponiveis.Contains(m.IdModulo) && m.IdMenu != null).Select(t => (Guid)t.IdMenu).ToList();

                    FilteredValues().Set(GetType().Name, modulos.ToList());
                }

                return FilteredValues().Get<Guid>(GetType().Name);
            });

Any ideas to make an Inner Join automatically when the library to identify the property is a NavigationProperty?

DisableFilter extension not working correctly with "Contains()"-filter

Hi,
Im having a problem with a Linq filter that uses the Contains() operator.
When the filter is active, the DbSet returns only the entities that match the filter, but when i use the DisableFilter() extension to disable the filter, the DbSet returns no entities (instead of all entities).

Here is an example that shows the issue.
C# Console Application with the following NuGet packages:
EntityFramework version="6.1.2"
EntityFramework.DynamicFilters version="1.3.2"

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using EntityFramework.DynamicFilters;

namespace DynamicFilters
{
    class Program
    {
        static void Main()
        {
            var context = new Context();

            // Seed 10 entities.
            Enumerable.Range(1, 10)
                .Select(i => new Entity { Value = i })
                .ToList()
                .ForEach(entity => context.Entities.Add(entity));
            context.SaveChanges();

            // Get filtered entities.
            var entities = context.Entities.ToList();
            Console.WriteLine("Filter enabled : {0}", String.Join(",", entities));

            // Get unfiltered entities.
            context.DisableFilter("ContainsFilter");
            entities = context.Entities.ToList();
            Console.WriteLine("Filter disabled: {0}", String.Join(",", entities));

            // Wait
            Console.WriteLine("End. Press key...");
            Console.ReadKey();
        }
    }

    class Context : DbContext
    {
        public IDbSet<Entity> Entities { get; set; }

        static Context()
        {
            Database.SetInitializer(new DropCreateDatabaseAlways<Context>());
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            var valuesToShow = new List<int> { 1, 2, 3, 4 };
            modelBuilder.Filter("ContainsFilter",
                (Entity entity, List<int> values) => values.Contains(entity.Value),
                valuesToShow);

            base.OnModelCreating(modelBuilder);
        }
    }

    class Entity
    {
        public int Id { get; set; }
        public int Value { get; set; }

        public override string ToString()
        {
            return Value.ToString();
        }
    }
}

Here are the queries that get sent to the SQL Server
With filter enabled:

(@DynamicFilterParam_ContainsFilter_values int)SELECT 
    [Var_1].[Id] AS [Id], 
    [Var_1].[Value] AS [Value]
    FROM [dbo].[Entities] AS [Var_1]
    WHERE [Var_1].[Value] in (@DynamicFilterParam_ContainsFilter_values, 2, 3, 4)

With filter disabled:

(@DynamicFilterParam_ContainsFilter_values int)SELECT 
    [Var_1].[Id] AS [Id], 
    [Var_1].[Value] AS [Value]
    FROM [dbo].[Entities] AS [Var_1]
    WHERE [Var_1].[Value] = @DynamicFilterParam_ContainsFilter_values

Multiple includes with filters enabled cause field mismatches.

I don't know how to explain this, but essentially if I run a query and include multiple navigation entities, and on some of those, I include other child entities, the query becomes quite complex, and I started seeing properties being returned with values that weren't correct. When I compared the query generated with the filters to the one without and ran them against my database, I found the column that contained the proper data in the unfiltered query ,and it was different then the same column after.

I will likely need to make you a reproduction, but in the dynamic filtered query the columns I found incorrect are:

Join7.CropID AS CropID2,
Join7.Name AS Name5,
Join7.Abbreviation AS Abbreviation2,
Join7.CompanyID AS CompanyID4,
Join7.Active AS Active8,
Join7.Created AS Created8,
Join7.CreatedBy AS CreatedBy7,
Join7.Edited AS Edited8,
Join7.EditedBy AS EditedBy7,

When I run the same with Dynamic Filters removed, those columns are:
Join7.CROPID2 AS CropID2,
Join7.NAME2 AS Name5,
Join7.ABBREVIATION2 AS Abbreviation2,
Join7.COMPANYID2 AS CompanyID4,
Join7.ACTIVE4 AS Active8,
Join7.CREATED4 AS Created8,
Join7.CREATEDBY3 AS CreatedBy7,
Join7.EDITED4 AS Edited8,
Join7.EDITEDBY3 AS EditedBy7,

Without the repro, I can tell you that My entities have properties like "PreviousCrop" and "CurrentCrop" that both point to a Crop Type, or in this case I have entities like so:

Contract:
ID
Name

ContractToCropYear:
ID
ContractID
CropYearID

CropYear:
ID
PreviousCrop
CurrentCrop
CurrentVariety

Crop:
ID
Name

Variety:
ID
Name
CropID
OtherInfo

Essentially when I ask the context for a contract including all ContractToCropYears, Including all CropYears, Including the PreviousCrop, CurrentCrop, and Variety, the filtered queries generated (on MySQL) don't seem to track and match the correct projections.

I hope that made sense and that the explanation and examples can point you to where the issue might be. I am sure it has something to do with the 2 types of the different properties being the same, and so it matches to the wrong query.

Thanks you've been super helpful and responsive! I am still trying to find time to fix that interface issue I logged as I'd love to contribute rather then just find bugs!

Steve

Any way to handle soft deletes across relationships ?

Let's say I have a User entity and a Post entity. A Post belongs to a User.

// Simplified model
public class User {
  public int Id {get;set;}
  public string Email {get;set;}

  public bool IsDeleted {get;set;}
  public virtual IList<Post> Posts {get;set;}
}

public class Post {
  public int Id {get;set;}
  public string Title {get;set;}

  [ForeignKey("User_Id")]
  public virtual User {get;set;}
  public int User_Id {get;set;}
}

If I mark a User as deleted, can I configure a filter such that Posts by that User will not be returned from queries on the Posts ?

Remove embeded query when apply filtering

As I posted in a relevant issue of a similar repository when we apply a filtering through visitor and interceptors classes an embedded sql statement is added in the produced query. For example the produced sql looks like
'SELECT [Id], [Category],[TenantId]
FROM
(SELECT [Id], [Category], [TenantId] FROM [ProductCategories] WHERE [TenantId] = @TenantID
) AS [Extent1]
WHERE [Extent1].[Id] = @p0',N'@TenantID nvarchar(128),@p0 bigint',@TenantID=N'f6d39662-2744-4377-b455-2cdf333d0f71',@p0=3'
instead of the much simpler query
'SELECT
[Id], [Category], [TenantId]
FROM [ProductCategories]
WHERE [Id] = @p0 AND [TenantId] = @TenantID',N'@TenantID nvarchar(128),@p0 bigint',@TenantID=N'f6d39662-2744-4377-b455-2cdf333d0f71',@p0=3'

DB First support

Dear jcachat,

"Access to DynamicFilters is done via extension methods in the EntityFramework.DynamicFilters namespace on the DbContext and DbModelBuilder classes."

OnModelCreating is called only once at CodeFirst stategy.

What if someone would like to use this filter with Database First strategy?

Bests,
Boolish

StartsWith filter

Is there any way to create a filter with StartsWith using DynamicFilters?

Unable to DisableFilter() for a single column equality only filter.

I am receiving a "Filter name {0} not found" error while calling DisableFilter() on a single column equality-only filter:

Test snippet:

modelBuilder.Filter("EntityCFilter", (EntityC b) => (b.DeleteTimestamp == null));

...

context.DisableFilter("EntityCFilter");

Yields the error noted above. From what I can tell from the source, the filter is not actually registered correctly for single column equality only filter. So, subsequently it can't be found to be disabled.

I have a change for the Filter() single column scenario, but I'm not sure it's "correct".

Filtering included properties

This issue is a little different then I first thought. You can filter included properties, but not if they are already cached within the context. In my unit test I was not disposing of the context that contained my test object after saving the delete.

Filters based on Interfaces only work for implicit implementation

When using interface based filters in VB.Net, if the interface property has a different name than the property in the object implementing it, the filter is not applied. For example

public interface IBlogPost
    Property PrimaryKey as long
end interface

public class BlogPost
    implements IBlogPost
    public property ID as Long Implements IBlogPost.PrimaryKey
end class

If a filter for IBlogPost is defined, it will not be applied.

Need support for <= and >=

Currently I am using jbogard's filters (modified to prevent it from caching the queries. I would love to switch over to your framework, but we need support for <= and >= filters, == is not enough for our use cases. Any chance of this being added?

EntityCommandCompilationException occurs for temporal entity filter

First of all, thanks for all your hard work on this much needed project!

I'm getting an exception when I try implement a filter on my temporal entities. I will provide below the code for a simple Console application which demonstrates the issue as well as the full stack trace of the exception thrown.

Code:

using System;
using System.Data.Entity;
using System.Linq;
using EntityFramework.DynamicFilters;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Database.SetInitializer(new DropCreateDatabaseAlways<TestDbContext>());
            using (var context = new TestDbContext())
            {
                context.TemporalEntities.Add(new TemporalEntity());
                context.TemporalEntities.Add(new TemporalEntity {DeleteTimestamp = DateTime.Now});
                context.SaveChanges();
                Console.WriteLine("Entity count: {0}", context.TemporalEntities.Count());
            }
            Console.Write("Press any key to exit.");
            Console.ReadKey();
        }

        public interface ITemporalEntity
        {
            int Id { get; set; }
            DateTime CreateTimestamp { get; set; }
            DateTime? DeleteTimestamp { get; set; }
        }

        public class TemporalEntity : ITemporalEntity
        {
            public TemporalEntity()
            {
                CreateTimestamp = DateTime.Now;
            }

            public int Id { get; set; }
            public DateTime CreateTimestamp { get; set; }
            public DateTime? DeleteTimestamp { get; set; }
        }

        public class TestDbContext : DbContext
        {
            public DbSet<TemporalEntity> TemporalEntities { get; set; }

            protected override void OnModelCreating(DbModelBuilder mb)
            {
                //This works:
                //mb.Filter("TemporalFilter", (ITemporalEntity te, DateTime dt) => (te.CreateTimestamp <= dt), () => DateTime.Now);

                // This doesn't:
                mb.Filter(
                    "TemporalFilter",
                    (ITemporalEntity te, DateTime dt) => ((te.CreateTimestamp <= dt) && ((te.DeleteTimestamp == null) || (te.DeleteTimestamp > dt))),
                    () => DateTime.Now);
            }
        }
    }
}

Exception:

A first chance exception of type 'System.Data.Entity.Core.EntityCommandCompilationException' occurred in EntityFramework.SqlServer.dll
System.Transactions Critical: 0 : <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>ConsoleApplication1.vshost.exe</AppDomain><Exception><ExceptionType>System.Data.Entity.Core.EntityCommandCompilationException, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>An error occurred while preparing the command definition. See the inner exception for details.</Message><StackTrace>   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)
   at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateCommandDefinition(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver)
   at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContext context, DbQueryCommandTree tree)
   at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Boolean streaming, Span span, IEnumerable`1 compiledQueryParameters, AliasGenerator aliasGenerator)
   at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.&amp;lt;&amp;gt;c__DisplayClass7.&amp;lt;GetResults&amp;gt;b__6()
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.&amp;lt;&amp;gt;c__DisplayClass7.&amp;lt;GetResults&amp;gt;b__5()
   at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.&amp;lt;System.Collections.Generic.IEnumerable&amp;lt;T&amp;gt;.GetEnumerator&amp;gt;b__0()
   at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
   at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
   at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.&amp;lt;GetElementFunction&amp;gt;b__3[TResult](IEnumerable`1 sequence)
   at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
   at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
   at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression)
   at System.Linq.Queryable.Count[TSource](IQueryable`1 source)
   at ConsoleApplication1.Program.Main(String[] args) in d:\Users\Chris\Documents\Visual Studio 2013\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 18
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()</StackTrace><ExceptionString>System.Data.Entity.Core.EntityCommandCompilationException: An error occurred while preparing the command definition. See the inner exception for details. ---&amp;gt; System.NotImplementedException: Unhandled Type of Nullable`1 for Constant value null in LambdaToDbExpressionVisitor.VisitConstant
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitConstant(ConstantExpression node)
   at System.Linq.Expressions.ConstantExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitUnary(UnaryExpression node)
   at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitBinary(BinaryExpression node)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitBinary(BinaryExpression node)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitBinary(BinaryExpression node)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.Convert(DynamicFilterDefinition filter, DbExpressionBinding binding, ObjectContext objectContext)
   at EntityFramework.DynamicFilters.DynamicFilterQueryVisitor.BuildFilterExpressionWithDynamicFilters(String entityName, IEnumerable`1 filterList, DbExpressionBinding binding, DbExpression predicate)
   at EntityFramework.DynamicFilters.DynamicFilterQueryVisitor.Visit(DbScanExpression expression)
   at System.Data.Entity.Core.Common.CommandTrees.DbScanExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitGroupExpressionBinding(DbGroupExpressionBinding binding)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbGroupByExpression expression)
   at System.Data.Entity.Core.Common.CommandTrees.DbGroupByExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBinding(DbExpressionBinding binding)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBindingEnterScope(DbExpressionBinding binding)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbProjectExpression expression)
   at System.Data.Entity.Core.Common.CommandTrees.DbProjectExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
   at EntityFramework.DynamicFilters.DynamicFilterInterceptor.TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
   at System.Data.Entity.Infrastructure.Interception.DbCommandTreeDispatcher.&amp;lt;Created&amp;gt;b__0(IDbCommandTreeInterceptor i, DbCommandTreeInterceptionContext c)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TInterceptionContext,TResult](TResult result, TInterceptionContext interceptionContext, Action`2 intercept)
   at System.Data.Entity.Infrastructure.Interception.DbCommandTreeDispatcher.Created(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)
   --- End of inner exception stack trace ---
   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)
   at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateCommandDefinition(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver)
   at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContext context, DbQueryCommandTree tree)
   at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Boolean streaming, Span span, IEnumerable`1 compiledQueryParameters, AliasGenerator aliasGenerator)
   at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.&amp;lt;&amp;gt;c__DisplayClass7.&amp;lt;GetResults&amp;gt;b__6()
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.&amp;lt;&amp;gt;c__DisplayClass7.&amp;lt;GetResults&amp;gt;b__5()
   at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.&amp;lt;System.Collections.Generic.IEnumerable&amp;lt;T&amp;gt;.GetEnumerator&amp;gt;b__0()
   at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
   at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
   at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.&amp;lt;GetElementFunction&amp;gt;b__3[TResult](IEnumerable`1 sequence)
   at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
   at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
   at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression)
   at System.Linq.Queryable.Count[TSource](IQueryable`1 source)
   at ConsoleApplication1.Program.Main(String[] args) in d:\Users\Chris\Documents\Visual Studio 2013\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 18
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()</ExceptionString><InnerException><ExceptionType>System.NotImplementedException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>Unhandled Type of Nullable`1 for Constant value null in LambdaToDbExpressionVisitor.VisitConstant</Message><StackTrace>   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitConstant(ConstantExpression node)
   at System.Linq.Expressions.ConstantExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitUnary(UnaryExpression node)
   at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitBinary(BinaryExpression node)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitBinary(BinaryExpression node)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitBinary(BinaryExpression node)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.Convert(DynamicFilterDefinition filter, DbExpressionBinding binding, ObjectContext objectContext)
   at EntityFramework.DynamicFilters.DynamicFilterQueryVisitor.BuildFilterExpressionWithDynamicFilters(String entityName, IEnumerable`1 filterList, DbExpressionBinding binding, DbExpression predicate)
   at EntityFramework.DynamicFilters.DynamicFilterQueryVisitor.Visit(DbScanExpression expression)
   at System.Data.Entity.Core.Common.CommandTrees.DbScanExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitGroupExpressionBinding(DbGroupExpressionBinding binding)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbGroupByExpression expression)
   at System.Data.Entity.Core.Common.CommandTrees.DbGroupByExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBinding(DbExpressionBinding binding)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBindingEnterScope(DbExpressionBinding binding)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbProjectExpression expression)
   at System.Data.Entity.Core.Common.CommandTrees.DbProjectExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
   at EntityFramework.DynamicFilters.DynamicFilterInterceptor.TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
   at System.Data.Entity.Infrastructure.Interception.DbCommandTreeDispatcher.&amp;lt;Created&amp;gt;b__0(IDbCommandTreeInterceptor i, DbCommandTreeInterceptionContext c)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TInterceptionContext,TResult](TResult result, TInterceptionContext interceptionContext, Action`2 intercept)
   at System.Data.Entity.Infrastructure.Interception.DbCommandTreeDispatcher.Created(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)</StackTrace><ExceptionString>System.NotImplementedException: Unhandled Type of Nullable`1 for Constant value null in LambdaToDbExpressionVisitor.VisitConstant
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitConstant(ConstantExpression node)
   at System.Linq.Expressions.ConstantExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitUnary(UnaryExpression node)
   at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitBinary(BinaryExpression node)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitBinary(BinaryExpression node)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitBinary(BinaryExpression node)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.Convert(DynamicFilterDefinition filter, DbExpressionBinding binding, ObjectContext objectContext)
   at EntityFramework.DynamicFilters.DynamicFilterQueryVisitor.BuildFilterExpressionWithDynamicFilters(String entityName, IEnumerable`1 filterList, DbExpressionBinding binding, DbExpression predicate)
   at EntityFramework.DynamicFilters.DynamicFilterQueryVisitor.Visit(DbScanExpression expression)
   at System.Data.Entity.Core.Common.CommandTrees.DbScanExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitGroupExpressionBinding(DbGroupExpressionBinding binding)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbGroupByExpression expression)
   at System.Data.Entity.Core.Common.CommandTrees.DbGroupByExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBinding(DbExpressionBinding binding)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionBindingEnterScope(DbExpressionBinding binding)
   at System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbProjectExpression expression)
   at System.Data.Entity.Core.Common.CommandTrees.DbProjectExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
   at EntityFramework.DynamicFilters.DynamicFilterInterceptor.TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
   at System.Data.Entity.Infrastructure.Interception.DbCommandTreeDispatcher.&amp;lt;Created&amp;gt;b__0(IDbCommandTreeInterceptor i, DbCommandTreeInterceptionContext c)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TInterceptionContext,TResult](TResult result, TInterceptionContext interceptionContext, Action`2 intercept)
   at System.Data.Entity.Infrastructure.Interception.DbCommandTreeDispatcher.Created(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)</ExceptionString></InnerException></Exception></TraceRecord>

DatabaseFirst

thanks a lot for your effort! Jcachat.
it is possible to use this solution with DatabaseFirst (EDMX) Approach?

Should not add any filter if it's disabled

Hi,

It adds some AND/OR expressions to Where condition of the Query even the filter is disabled. I think it will be better and more performant if it completely remove any conditions related to the filter if it's disabled. Is it possible?

Thanks a lot.

Ninject loses scope in filter method

I ran into an issue concerning using dependency injection (Ninject) with a dynamic filter. Here are the parameters of the problem:

  1. SystemContext (extension of DbContextBase -> DbContext), using a Ninject binding in "request" scope, which means the instance of the context is maintained for the lifetime of the HTTP request. So if I change the property "CurrentPartitionKey" on the instance, it should have the same value on the instance of SystemContext until the HTTP request ends.
  2. CurrentPartitionKey is changed based on the user's key when the SystemContext is created.
  3. I have the following filter:
mb.Filter("FilterPartition", (IPartitioned item, long? userKey, long bitMask) => {
     (!userKey.HasValue || !item.PartitionKey.HasValue || ((item.PartitionKey & bitMask) == userKey))
},
() => CurrentPartitionKey,
() => PartitionHelper.GetComparisonMask(CurrentPartitionKey)
  1. When I check the context property values while debugging, CurrentPartitionKey is 2, everywhere while stepping through the code... however when the filter is triggered from a Db query, CurrentPartitionKey is now NULL. When it exits the scope of the function where it retrieves CurrentPartitionKey, it is 2 again.

Is this intended behavior or does the filter contain a seperate instance of my DbContext class? Does it have a problem working alongside an IoC container that manages the context in the request scope?

I think I have a workaround by setting the argument values in the function (userKey and bitMask) via this.SetFilterScopeValue.

Please let me know if you have any insight into this, and if it is an issue or intended behavior?

Contains in queries with a Join

Hi John,

Some background:
I'm creating an multi-tenant application that adds a Guid property named Tenant and your code is really making it easy to do this. In the application the tenants can have other tenants as their parent (some data is application wide and is in the root tenant, some application data is country specific that is in a tenant with the root tenant as parent and then their is a company tenant where the company specific data sits).

When a user is operating in a tenant that has a parent tenant than it should be able to query it's own data + the data of it's parent and so the filter I'm uses a Contains() that takes a list of Guid's representing the tenants.

Everything is working perfect for single tables, but when there is join in the table the query that get's joined with the base table only get's the first tenant from the list included in it's where.

I pulled some queries that were being generated from the sql profiler, and here you can see that the MeteringPoints table where statement has a full list in the where clause but the query that it joins only has an equal equation.

exec sp_executesql N'SELECT 
    [Project1].[C1] AS [C1], 
    [Project1].[Id] AS [Id], 
    [Project1].[Ean_Code] AS [Ean_Code], 
    [Project1].[ProductId] AS [ProductId], 
    [Project1].[AddressId] AS [AddressId], 
    [Project1].[AllocationTimeSeriesId] AS [AllocationTimeSeriesId], 
    [Project1].[Comment] AS [Comment], 
    [Project1].[Tenant] AS [Tenant], 
    [Project1].[Id1] AS [Id1], 
    [Project1].[Street] AS [Street], 
    [Project1].[Number] AS [Number], 
    [Project1].[Addition] AS [Addition], 
    [Project1].[City] AS [City], 
    [Project1].[PostalCode] AS [PostalCode], 
    [Project1].[CountryCode] AS [CountryCode], 
    [Project1].[LocationDescription] AS [LocationDescription], 
    [Project1].[Longitude] AS [Longitude], 
    [Project1].[Latitude] AS [Latitude], 
    [Project1].[Tenant1] AS [Tenant1]
    FROM ( SELECT 
        [Extent1].[Id] AS [Id], 
        [Extent1].[Ean_Code] AS [Ean_Code], 
        [Extent1].[ProductId] AS [ProductId], 
        [Extent1].[AddressId] AS [AddressId], 
        [Extent1].[AllocationTimeSeriesId] AS [AllocationTimeSeriesId], 
        [Extent1].[Comment] AS [Comment], 
        [Extent1].[Tenant] AS [Tenant], 
        1 AS [C1], 
        [Extent2].[Id] AS [Id1], 
        [Extent2].[Street] AS [Street], 
        [Extent2].[Number] AS [Number], 
        [Extent2].[Addition] AS [Addition], 
        [Extent2].[City] AS [City], 
        [Extent2].[PostalCode] AS [PostalCode], 
        [Extent2].[CountryCode] AS [CountryCode], 
        [Extent2].[LocationDescription] AS [LocationDescription], 
        [Extent2].[Longitude] AS [Longitude], 
        [Extent2].[Latitude] AS [Latitude], 
        [Extent2].[Tenant] AS [Tenant1]
        FROM   (SELECT [Var_11].[Id] AS [Id], [Var_11].[Ean_Code] AS [Ean_Code], [Var_11].[ProductId] AS [ProductId], [Var_11].[AddressId] AS [AddressId], [Var_11].[AllocationTimeSeriesId] AS [AllocationTimeSeriesId], [Var_11].[Comment] AS [Comment], [Var_11].[Tenant] AS [Tenant]
            FROM [dbo].[MeteringPoints] AS [Var_11]
            WHERE ([Var_11].[Tenant] in (@DynamicFilterParam_TenantFilter_tenantIds, ''2f6a477e-899a-4dad-8154-64693301efb8'', ''14bbc0d4-0f0e-46af-a69d-7efeb3c68853'')) OR (@DynamicFilterParam_TenantFilter_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent1]
        LEFT OUTER JOIN  (SELECT [Var_12].[Id] AS [Id], [Var_12].[Street] AS [Street], [Var_12].[Number] AS [Number], [Var_12].[Addition] AS [Addition], [Var_12].[City] AS [City], [Var_12].[PostalCode] AS [PostalCode], [Var_12].[CountryCode] AS [CountryCode], [Var_12].[LocationDescription] AS [LocationDescription], [Var_12].[Longitude] AS [Longitude], [Var_12].[Latitude] AS [Latitude], [Var_12].[Tenant] AS [Tenant]
            FROM [dbo].[Addresses] AS [Var_12]
            WHERE ([Var_12].[Tenant] = @DynamicFilterParam_TenantFilter_tenantIds) OR (@DynamicFilterParam_TenantFilter_DynamicFilterIsDisabled IS NOT NULL) ) AS [Extent2] ON [Extent1].[AddressId] = [Extent2].[Id]
    )  AS [Project1]
    ORDER BY [Project1].[Ean_Code] ASC
    OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY ',N'@DynamicFilterParam_TenantFilter_tenantIds uniqueidentifier,@DynamicFilterParam_TenantFilter_DynamicFilterIsDisabled bit',@DynamicFilterParam_TenantFilter_tenantIds='BE570BD7-93AE-4816-8A3E-FBF54D122518',@DynamicFilterParam_TenantFilter_DynamicFilterIsDisabled=NULL

Filter does not work with property with ComplexType

Hi,

I got an exception on this case. I have debugged, I see the method below does not return a proper column for a property of ComplexType.

  private static string ParseColumnNameFromExpression(LambdaExpression expression)
        {
            if (expression == null)
                throw new ArgumentNullException("Lambda expression is null");

            var body = expression.Body as MemberExpression;
            if ((body == null) || (body.Member == null) || string.IsNullOrEmpty(body.Member.Name))
            {
                //  The expression does not specify a column - it's a lambda expression/predicate that will need to
                //  be expanded by LabdaToDbExprssionVisitor during the query evaluation.
                return null;
            }

            var propertyExpression = body.Expression as MemberExpression;
            if ((propertyExpression != null) && (propertyExpression.Member != null) && (propertyExpression.Member.Name != body.Member.Name))
            {
                //  The expression is a property accessor - i.e. field.HasValue.  It's a lambda expression/predicate
                return null; // <== __problem at this line__
            }

            return body.Member.Name;
        }

Cheers,
Hung Tran

New Feature - Add Linq/Lambda support

Hello friend,
Your article is sensational.
But, I have a need here, and could not identify how can I do.
Here's an example:
modelBuilder.Filter ("MyEntity" (MyEntity p) => { var myArray = new [] {1,2,5,8,20,30};
return myArray.Contains (p.MyEntityID); });
Is there any way to do this?
Consider that myArray can be dynamic.

NotSupportedException - Non-generic collection

I'm getting this NotSupportedException "Non generic collections or System.Object types are not supported" but it's being thrown on first access of a generic collection:

public virtual IDbSet<LibraryNode> LibraryNodes { get; set; }

first accessed:

dbContext.LibraryNodes.Any()

Filter restrictions

This is more a question then an issue:
I added an global (interface) filter that filters all entrys for a specific companyId. I also added this filter to my user table but as it turns out the aspnet identity provider needs the full table scope to find the right user to login and I can't really add filter disable rules into the framework.
Is there another posibillity to disable filters for framework code or something like that? any ideas?
I thought about a second db connection but I have to eval first if this is possible..

Filter on navigation property

I am not really sure on whether this is an issue, so bear over with me if this is a behaviour "by design".

I need to set up a filter based on a navigation property -- see below my model:

public class MyEntity
{
public int ID {get; set;}

   public MyNavigationPropertyOnMyEntity Property1 {get; set;}

}

public class MyNavigationPropertyOnMyEntity
{
public int Type {get; set;}
}

I set up a filter like below:

modelBuilder.Filter("MyFilter", (MyEntity) => s.Property1.Type == 1);

But I get the following exception:

"Property MyNavigationPropertyOnMyEntity not found in Entity Type MyEntity"

Wrong SQL generation on Nullable filter values when it's null

Hi,

I have multi-tenancy filter where it's value can be null (like int?).

When filter's value is set to a non-null value like 1, there is no problem. But when I set filter's value to NULL, I expect to get entities which have a NULL TenantId. But it can not.

I see that generated SQL is wrong:

exec sp_executesql N'SELECT TOP (1) 
    [Extent1].[Id] AS [Id], 
    [Extent1].[ShouldChangePasswordOnNextLogin] AS [ShouldChangePasswordOnNextLogin], 
    [Extent1].[TenantId] AS [TenantId], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[Surname] AS [Surname]
    FROM [dbo].[AbpUsers] AS [Extent1]
    WHERE 
    (([Extent1].[TenantId] = @DynamicFilterParam_MayHaveTenant_TenantId) OR (@DynamicFilterParam_MayHaveTenant_DynamicFilterIsDisabled IS NOT NULL)) AND
     (1 = [Extent1].[Id])', 
    N'@DynamicFilterParam_MayHaveTenant_TenantId int,@DynamicFilterParam_MayHaveTenant_DynamicFilterIsDisabled bit',    
    @DynamicFilterParam_MayHaveTenant_TenantId=NULL,
    @DynamicFilterParam_MayHaveTenant_DynamicFilterIsDisabled=NULL

Look at here:

[Extent1].[TenantId] = @DynamicFilterParam_MayHaveTenant_TenantId

If the value is NULL, it will be like that:

[Extent1].[TenantId] = NULL

and as you know, comparing null should not be like that. Right syntax is:

[Extent1].[TenantId] IS NULL

We should use IS operator instead of = operator. Can you fix it.

Thanks.

Bug in properties with _

i tried for an hour to figure out why the parameter passed to the query was always null. Example.

addFilter("Notes_User", Blog b => b.parent_id, () => getid());

Had to rename parent_id to parentid.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.