Skip to content

Commit

Permalink
Query: Update EntityProjection when filtering on derived type
Browse files Browse the repository at this point in the history
Resolves #16217
  • Loading branch information
smitpatel committed Aug 6, 2019
1 parent b4c4a1a commit 47a8a1f
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 5 deletions.
17 changes: 15 additions & 2 deletions src/EFCore.Relational/Query/EntityProjectionExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,21 @@ public virtual EntityProjectionExpression UpdateEntityType(IEntityType derivedTy
{
return new EntityProjectionExpression(derivedType, _innerTable, _nullable);
}

throw new InvalidOperationException("EntityProjectionExpression: Cannot update EntityType when _innerTable is null");
else
{
var propertyExpressionCache = new Dictionary<IProperty, ColumnExpression>();
foreach (var kvp in _propertyExpressionsCache)
{
var property = kvp.Key;
if (derivedType.IsAssignableFrom(property.DeclaringEntityType)
|| property.DeclaringEntityType.IsAssignableFrom(derivedType))
{
propertyExpressionCache[property] = kvp.Value;
}
}

return new EntityProjectionExpression(derivedType, propertyExpressionCache);
}
}

public virtual IEntityType EntityType { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -655,8 +655,7 @@ private bool CompareIncludes(Expression outer, Expression inner)
if (outer is EntityReference outerEntityReference
&& inner is EntityReference innerEntityReference)
{
return outerEntityReference.EntityType == innerEntityReference.EntityType
&& outerEntityReference.IncludePaths.Equals(innerEntityReference.IncludePaths);
return outerEntityReference.IncludePaths.Equals(innerEntityReference.IncludePaths);
}

if (outer is NewExpression outerNewExpression
Expand Down
15 changes: 14 additions & 1 deletion test/EFCore.Specification.Tests/Query/InheritanceTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ public virtual void OfType_Union_subquery()
}
}

[ConditionalFact(Skip = "#16217")]
[ConditionalFact(Skip = "#16298")]
public virtual void OfType_Union_OfType()
{
using (var context = CreateContext())
Expand All @@ -525,6 +525,19 @@ public virtual void OfType_Union_OfType()
}
}

[ConditionalFact]
public virtual void Subquery_OfType()
{
using (var context = CreateContext())
{
context.Set<Bird>()
.Take(5)
.Distinct() // Causes pushdown
.OfType<Kiwi>()
.ToList();
}
}

[ConditionalFact(Skip = "#16298")]
public virtual void Union_entity_equality()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,29 @@ WHERE [a0].[Discriminator] IN (N'Eagle', N'Kiwi') AND ([a0].[Discriminator] = N'
WHERE ([t].[FoundOn] = CAST(0 AS tinyint)) AND [t].[FoundOn] IS NOT NULL");
}

public override void OfType_Union_OfType()
{
base.OfType_Union_OfType();

AssertSql(" ");
}

public override void Subquery_OfType()
{
base.Subquery_OfType();

AssertSql(
@"@__p_0='5'
SELECT DISTINCT [t].[Species], [t].[CountryId], [t].[Discriminator], [t].[Name], [t].[EagleId], [t].[IsFlightless], [t].[FoundOn]
FROM (
SELECT TOP(@__p_0) [a].[Species], [a].[CountryId], [a].[Discriminator], [a].[Name], [a].[EagleId], [a].[IsFlightless], [a].[Group], [a].[FoundOn]
FROM [Animal] AS [a]
WHERE [a].[Discriminator] IN (N'Eagle', N'Kiwi')
) AS [t]
WHERE [t].[Discriminator] = N'Kiwi'");
}

public override void Union_entity_equality()
{
base.Union_entity_equality();
Expand Down

0 comments on commit 47a8a1f

Please sign in to comment.