Created
October 16, 2018 18:45
-
-
Save cyptus/f9ac8bb74b2a7d98d148326502600d40 to your computer and use it in GitHub Desktop.
ef core hasqueryfilter exception on include
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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