efcore: OwnsMany cannot use HasQueryFilter
We are in the progress of trying to upgrading to use EF Core 2.2 And found that OwnsMany have some restriction.
Steps to reproduce
Example:
Models
public class User
{
public Guid UserId { get; set; }
public string Email { get; set; }
public IEnumerable<Profile> Profiles { get; set; }
}
public class Profile
{
public Guid ProfileId { get; set; }
public string Email { get; set; }
public bool IsActive { get; set; }
}
DbContext
protected override void OnModelCreating(ModelBuilder builder)
{
#region User
builder.Entity<User>(m =>
{
#region Mappings
m.ToTable("User", "user");
m.HasKey(x => x.UserId);
m.OwnsMany(x => x.Profiles, b =>
{
b.HasForeignKey(p => p.Email);
b.HasPrincipalKey(u => u.Email);
});
#endregion
});
builder.Entity<Profile>(m =>
{
#region Mappings
m.ToTable("Profile", "user");
m.HasKey(x => x.ProfileId);
m.HasQueryFilter(x => x.IsActive);
#endregion
});
#endregion
}
In this case, HasQueryFilter
will work properly and only IsActive
Profile being queried when I call this:
_dbContext.Set<User>().Include(u => u.Profiles)
However, when I want to simplify the OwnsMany relationship so no need to define Entity<Profile>
specificly
This will not work
protected override void OnModelCreating(ModelBuilder builder)
{
#region User
builder.Entity<User>(m =>
{
#region Mappings
m.ToTable("User", "user");
m.HasKey(x => x.UserId);
m.OwnsMany(x => x.Profiles, b =>
{
b.ToTable("Profile", "user");
b.HasKey(x => x.ProfileId);
b.HasQueryFilter(x => x.IsActive);
b.HasForeignKey(p => p.Email);
b.HasPrincipalKey(u => u.Email);
});
#endregion
});
#endregion
}
As CollectionOwnershipBuilder
do not have HasQueryFilter
Further technical details
EF Core version: 2.2 Database Provider: Microsoft.EntityFrameworkCore.SqlServer Operating system: Windows 10 IDE: Visual Studio 2017 15.9.3
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 1
- Comments: 15 (8 by maintainers)
In EF Core 5.0 I get this warning:
If the configuration is like this:
… one solution is to add:
But if Blog owns Post I cannot use HasQueryFilter on Post.
After discussing this with @AndriySvyryd, and reading a bit online about this kind of scenario in the context of DDD, here are my thoughts:
TL;DR: I don’t think we need to decide anything for 3.0 here, so adding propose-punt label.
Aggregates that are too large as to need filtering are a smell. If we want ownership/aggregates to become a pit of success feature, an API that steers customers to design smaller aggregates may help.
On the other hand, it is ok to have useful lower-level features that allow customers to do more advanced things, plus not all our customers want to necessary become DDD practitioners. Both rule-based eager loading and query filters are such low-level features.
Precisely because query filters is one of those low-level feature for which it is ok to not always result on consistent behaviors (a well-know example of inconsistency happens when you load a dependent of a principal that has been filtered out: you get dependent with a dangling FK value, but no apparent principal object), I don’t want us to take a dogmatic position and say now that we never want to allow this. I prefer to wait for feedback.
I think if we end up enabling query filters for owned objects and then that doesn’t work with document oriented database, that is still all right. It is just a consequence of restrictions in the query capabilities of the database (e.g. one full document at the time).