Skip to content

WithExpressionExpanding not expanding LINQ queries properly #186

@JKamsker

Description

@JKamsker

I'm experiencing an issue with WithExpressionExpanding where it does not properly expand LINQ queries. The application throws a System.InvalidOperationException when using a custom expression within a query. However, manually expanding the expression using Expand() works as expected.

Steps to Reproduce

Here's a simplified example that demonstrates the issue:

  1. Create a custom expression:
public class Version
{
    public int Id { get; set; }
    public int Major { get; set; }
    public int Minor { get; set; }
    public int Patch { get; set; }
    public string Tag { get; set; }
}

public class ProductVersion
{
    public int Id { get; set; }
    public Version Version { get; set; }
}

Expression<Func<Version, Version, bool>> IsEqual = 
            (version1, version2) => (version1.Major == version2.Major && version1.Minor == version2.Minor && version1.Patch == version2.Patch && version1.Tag == version2.Tag);

Expression<Func<ProductVersion, bool>> b = x => IsEqual.Invoke(x.Version, toFind);
    Configure EF Core with `WithExpressionExpanding`:
  // Configure EF Core
  builder.Services.AddDbContextPool<UpdateServerContext>
  (
      options => options
          .UseSqlServer(connectionString, sql => { sql.EnableRetryOnFailure(10); })
          .EnableSensitiveDataLogging(false)
          .WithExpressionExpanding()
  );
    Execute the query:
  var result = ctx.ProductVersions
    .Where(b)
    .ToList();

Expected Behavior

The query should execute successfully and return the expected results.

Actual Behavior

A System.InvalidOperationException is thrown:

System.InvalidOperationException
  HResult=0x80131509
  Message=The LINQ expression 'DbSet<ProductVersion>()
    .Join(
        inner: DbSet<Version>(), 
        outerKeySelector: p => EF.Property<int?>(p, "VersionId"), 
        innerKeySelector: a => EF.Property<int?>(a, "Id"), 
        resultSelector: (o, i) => new TransparentIdentifier<ProductVersion, Version>(
            Outer = o, 
            Inner = i
        ))
    .Where(p => p.Inner.Major == __toFind_0.Major && p.Inner.Minor == __toFind_0.Minor && p.Inner.Patch == __toFind_0.Patch && p.Inner.Tag == __toFind_0.Tag)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com

Workaround 1

Manually expanding the expression using Expand() works:

var expanded = b.Expand();
var result = ctx.ProductVersions
  .Where(expanded)
  .ToList();

Workaround 2

Using the AsExpandable() extension method works:

var result = ctx.ProductVersions
  .AsExpandable()
  .Where(b)
  .ToList();

Environment

  • LinqKit.Microsoft.EntityFrameworkCore version: 7.1.4
  • .NET version: 6
  • Microsoft.EntityFrameworkCore: 7.0.5
  • Database provider: Microsoft.EntityFrameworkCore.SqlServer
  • Operating system: Windows 10

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions