示例#1
0
        static void Main(string[] args)
        {
            //  Run a query for each Account using the default/global filters.
            var context1 = new ExampleContext();

            //  Test for multiple navigation properties - issue #17
            var list = context1.EntityASet.Include(a => a.Nav1).Include(a => a.Nav2).Include(a => a.Nav3).ToList();

            System.Diagnostics.Debug.Assert((list.Count == 2) && (list[0].Nav1 != null) && (list[0].Nav2 == null) && (list[1].Nav1 != null) && (list[1].Nav2 == null));

            //var secondContext = new SecondContext();

            //var list = context1.BlogEntries.ToList();
            //Console.WriteLine("Got {0} items", list.Count());

            //context1.DisableFilter("BlogContainsTest");
            //list = context1.BlogEntries.ToList();
            //Console.WriteLine("Got {0} items", list.Count());

            //list = secondContext.BlogEntries.ToList();
            //System.Diagnostics.Debug.Print("Got {0} items", list.Count());

            Console.WriteLine("");
            Console.WriteLine("Querying with IsDeleted filter enabled");
            Query(context1, "homer", 2, true);
            Query(context1, "bart", 3, true);

            {
                //  Query each account with the IsDeleted filter disabled.  The filter is disabled
                //  by setting the value to null using SetFilterScopedParameterValue() so that it applies
                //  ONLY to this context and will not affect any other active or future contexts.
                var context2 = new ExampleContext();
                context2.DisableFilter("BlogEntryFilter");

                Console.WriteLine("");
                Console.WriteLine("Querying with BlogEntryFilter filter disabled");
                Query(context2, "homer", 9, false);
                Query(context2, "bart", 9, false);

                //  Re-enable the filter and query for deleted records
                context2.EnableFilter("BlogEntryFilter");
                context2.SetFilterScopedParameterValue("BlogEntryFilter", "isDeleted", true);
                Console.WriteLine("");
                Console.WriteLine("Querying for deleted records only");
                Query(context2, "homer", 2, true, true);
                Query(context2, "bart", 2, true, true);
            }

            //  Re-query using the original context1 object to demonstrate that the changes
            //  made to context2 have no effect on it and were properly scoped.
            Console.WriteLine("");
            Console.WriteLine("Re-Querying with original context");
            Query(context1, "homer", 2, true);
            Query(context1, "bart", 3, true);

            Console.WriteLine("");
            Console.WriteLine("");
            Console.WriteLine("Press enter to close...");
            Console.ReadLine();
        }
        private static void Query(ExampleContext context, string userName, int expected, bool blogFilterIsEnabled, bool reusedContext = false)
        {
            var account = context.Accounts
                          .Include(a => a.BlogEntries)
                          .Where(a => a.UserName == userName).FirstOrDefault();

            //  Set the CurrentAccountID in the static/global property used in the filter definition (see ExampleContext.OnModelCreating)
            //  For creating a filter on the current user, this could come from the Thread.CurrentPrincipal...
            ExampleContext.CurrentAccountID = account.ID;

            if (blogFilterIsEnabled)
            {
                //  Don't do this check if the blog filter is disabled.  Otherwise, the blog records in account.BlogEntries
                //  will be filtered by the Account.ID while allBlogEntries will not (since the AccountID filter is now
                //  part of the "BlogEntryFilter" filter).

                //  Test to make sure that Include()'d collections are also filtered
                var allBlogEntries = context.BlogEntries.ToList();
                if (account.BlogEntries.Count != allBlogEntries.Count)
                {
                    //  This will happen if the context is being reused and EF already has other blog entries cached.  Those
                    //  cached objects will be automatically attached to the account object even if they do not match the
                    //  current sql query filter.  There is nothing that can be done about this.  Care should be taken to
                    //  not re-use the same DbContext when filter values are changed.
                    //  See https://github.com/jcachat/EntityFramework.DynamicFilters/issues/5
                    System.Diagnostics.Debug.Print("account.BlogEntries={0}, allBlogEntries={1}, reusedContext={2}", account.BlogEntries.Count, allBlogEntries.Count, reusedContext);
                    System.Diagnostics.Debug.Assert(reusedContext);
                }
            }

            //  Query blog entries.  This will use the global filter created in ExampleContext.OnModelCreating.
            //  Filter on IsActive is to reproduce a situation seen with MySQL that was adding those filters and not enclosing them in ()'s so the
            //  'or' condition here was not properly enclosed - caused our dynamic filters to not be used correctly.
            bool?active      = true;
            var  blogEntries = context.BlogEntries.Where(b => (!active.HasValue || (b.IsActive == active.Value))).ToList();

            System.Diagnostics.Debug.Assert(blogEntries.Count == expected);

            Console.WriteLine(string.Format("Current User = {0}: Selected {1} blog entries", userName, blogEntries.Count));
            if (blogEntries.Count != expected)
            {
                Console.WriteLine(string.Format("  *** Expected {0} blog entries!", expected));
            }
        }