Skip to content

Instantly share code, notes, and snippets.

@cyptus
Created October 16, 2018 18:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cyptus/f9ac8bb74b2a7d98d148326502600d40 to your computer and use it in GitHub Desktop.
Save cyptus/f9ac8bb74b2a7d98d148326502600d40 to your computer and use it in GitHub Desktop.
ef core hasqueryfilter exception on include
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
namespace EFCoreTest
{
public class Program
{
public static int MinPriority;
static void Main(string[] args)
{
Console.WriteLine("Init...");
InitData();
Console.WriteLine("\r\n\r\n### Static Query: ###\r\n");
PrintData<StaticQueryDbContext>();
Console.WriteLine("\r\n\r\n### Dynamic Query: ###\r\n");
PrintData<DynamicQueryDbContext>();
Console.ReadLine();
}
static void PrintData<TDbContext>() where TDbContext : AppDbContext, new()
{
Console.WriteLine("\r\nData Items Prio 15...");
MinPriority = 15;
PrintItems<TDbContext>();
Console.WriteLine("\r\nData Items Prio 35...");
MinPriority = 35;
PrintItems<TDbContext>();
Console.WriteLine("\r\nData Groups Prio 15...");
MinPriority = 15;
PrintGroups<TDbContext>();
Console.WriteLine("\r\nData Groups Prio 35...");
MinPriority = 35;
PrintGroups<TDbContext>();
}
static void InitData()
{
using (var context = new StaticQueryDbContext())
{
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
context.Add(new Group()
{
Name = "Group #1",
Items = new List<GroupItem>()
{
new GroupItem()
{
Name = "GroupItem #1",
Priority = 10
},
new GroupItem()
{
Name = "GroupItem #2",
Priority = 20
}
}
});
context.Add(new Group()
{
Name = "Group #2",
Items = new List<GroupItem>()
{
new GroupItem()
{
Name = "GroupItem #3",
Priority = 30
},
new GroupItem()
{
Name = "GroupItem #4",
Priority = 40
}
}
});
context.SaveChanges();
}
}
static void PrintItems<TDbContext>() where TDbContext : AppDbContext, new()
{
Console.WriteLine("Items:");
using (var context = new TDbContext())
{
var items = context.GroupItems.ToList();
items.ForEach(Console.WriteLine);
}
}
static void PrintGroups<TDbContext>() where TDbContext : AppDbContext, new()
{
Console.WriteLine("Groups:");
using (var context = new TDbContext())
{
try
{
var groups = context.Groups.Include(x => x.Items).ToList();
groups.ForEach(group =>
{
var itemNames = String.Join(", ", group.Items);
Console.WriteLine($"{group.Name}: {itemNames}");
});
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
}
}
}
}
public class StaticQueryDbContext : AppDbContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//query filter is working with include, but Program.MinPriority change have no effect on already compiled query
modelBuilder.Entity<GroupItem>().HasQueryFilter(x => x.Priority >= Program.MinPriority);
}
}
public class DynamicQueryDbContext : AppDbContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//generating query expression on the fly fails for included data
modelBuilder.Entity<GroupItem>().HasQueryFilter(x => GenerateMyFilter()(x));
}
protected Func<GroupItem, bool> GenerateMyFilter()
{
return x => x.Priority >= Program.MinPriority;
}
}
public class AppDbContext : DbContext
{
public DbSet<Group> Groups { get; set; }
public DbSet<GroupItem> GroupItems { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer(@"Server=.\;Database=efcoretest;Trusted_Connection=True;MultipleActiveResultSets=true");
}
}
public class Group
{
[Key]
public int GroupId { get; set; }
public string Name { get; set; }
public virtual IEnumerable<GroupItem> Items { get; set; }
}
public class GroupItem
{
[Key]
public int GroupItemId { get; set; }
public string Name { get; set; }
public int Priority { get; set; }
public int GroupId { get; set; }
[ForeignKey(nameof(GroupId))]
public Group Group { get; set; }
public override string ToString()
{
return $"{Name} ({Priority})";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment