Unable to translate set operation after client-side projection
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
Hey, when trying to concat two results that are projected using concise C# records, I am getting an invalid operation exception with the error message _“Unable to translate set operation after client projection has been applied. Consider moving the set operation before the last 'Select' call.”_
When not attempting to use a concatenation/union, the the positional record syntax _does_ work, so it’s not that EF Core does not support the concise syntax here.
See the following example using the SQLite provider (but the same issue occurs with other database engines as well):
```csharp
var options = new DbContextOptionsBuilder().UseSqlite("Data Source=testdb.db").Options;
using var db = new TestContext(options);
db.Database.EnsureCreated();
// this works without any issues
var resultWithProperties = db.Test1
.Select(t => new ResultTypeProperties
{
Type = "Test 1",
Value = t.Value
})
.Concat(db.Test2.Select(t => new ResultTypeProperties
{
Type = "Test 2",
Value = t.Value
}))
.ToArray();
// this breaks with the exception “Unable to translate set operation after client projection has been applied.”
var resultWithRecords = db.Test1
.Select(t => new ResultTypeRecord("Test 1", t.Value))
.Concat(db.Test2
.Select(t => new ResultTypeRecord("Test 2", t.Value))
)
.ToArray();
// Note that the positional record syntax _is_ supported usually which you
// can see if you comment out the `.Concat()` calls to skip the union.
```
The types for this are declared as following:
```csharp
public class TestContext : DbContext
{
public DbSet Test1 { get; set; }
public DbSet Test2 { get; set; }
public TestContext(DbContextOptions options) : base(options) { }
}
public class Test1
{
public int Id { get; set; }
public string Value { get; set; }
}
public class Test2
{
public int Id { get; set; }
public string Value { get; set; }
}
public record ResultTypeProperties
{
public string Type { get; set; }
public string Value { get; set; }
}
public record ResultTypeRecord(string Type, string Value);
```
Note the different syntax used to declare the properties on `ResultTypeProperties` and `ResultTypeRecord`.
This example currently uses Microsoft.EntityFrameworkCore.Sqlite version 6.0.6.
Contributor guide
Assessment
This issue has not been assessed yet.