Home > database >  How to access a TPH type's property in a LINQ expression tree?
How to access a TPH type's property in a LINQ expression tree?

Time:12-10

I have 2 SQL Server tables, Order and OrderDetail. I have 3 C# classes based on those tables: Order maps to table Order, while OrderDetail and SpecialOrderDetail map to table OrderDetail using TPH with OrderDetail being an abstract base class and the concrete SpecialOrderDetail inherits from it.

I need to get all Orders with Type 0 or has a SpecialOrderDetail with SpecialType 0. I thought this would be possible:

var orders = database.Order.Where(od => od.Type == 0
    || (od.Detail is SpecialOrderDetail sp && sp.SpecialType == 0)).ToList();

But Visual Studio gave this error: CS8122: An expression tree may not contain an 'is' pattern-matching operator.

I can't move the property Type from SpecialOrderDetail to the OrderDetail. I think I can do this instead:

var orders = database.Order.Where(od => od.Type == 0
    || od.Detail is SpecialOrderDetail).ToList();
orders.RemoveAll(od => od.Type != 0
    && od.Detail is SpecialOrderDetail sp && sp.SpecialType != 0);

This way I have to repeat the Type check in 2 statements, which isn't bad but in the future there may be more checks in place, and pull unneeded records from the DB just to filter them out immediately. Without resorting to actual SQL statements, is there a way to put the SpecialType check directly in the DB query?

I'm using .NET Framework 4.8 and Entity Framework 6.1.3.

CodePudding user response:

While pattern-matching and casting are not supported in an expression tree, is and as works! I ended up using this:

var orders = database.Order.Where(od => od.Type == 0
    || (od.Detail is SpecialOrderDetail
        && (od.Detail as SpecialOrderDetail).SpecialType == 0)).ToList();
  • Related