Search code examples
c#entity-frameworkexpression-trees

Is replacing an assignment with an Expression possible?


I have a method of a Web API controller which queries the DB and returns data:

public IQueryable<DeviceInformation> GetAllRegisteredDevices()
{
    var result = this.db.CustomDeviceInstallations.Select(install => new DeviceInformation
    {
        Platform =
            install.Platform == NotificationPlatform.Apns ? PLATFORM.iOS :
            install.Platform == NotificationPlatform.Gcm ? PLATFORM.Android :
            PLATFORM.Unknown
    });

    return result;
}

What bugs me in this method is the decision about the platform being assigned. I will need the same decision in other contexts and therefore would like to extract it, so I ended up with:

public Expression<Func<NotificationPlatform, PLATFORM>> ToDeviceInfoPlatformExpression()
{
    return p =>
        p == NotificationPlatform.Apns ? PLATFORM.iOS :
        p == NotificationPlatform.Gcm ? PLATFORM.Android :
        PLATFORM.Unknown;
}

The question is now: how can I use my expression? Platform = ???? Is it possible at all?

Note: I know I could instead use an extension method and also use a switch-case for readability. However, the code above is used in context of Entity Framework and must be an expression. This also rules out the use of Expression.Compile().


Solution

  • Is not possible without some expression helper library.

    Here is how you can do that with LinqKit using AsExpandable and Invoke extension methods:

    // First you need to put the expression into a variable
    // Without that you'll get the famous EF method not supported exception
    var deviceInfoPlatform = ToDeviceInfoPlatformExpression();
    // Then you can use it inside the query
    var result = this.db.CustomDeviceInstallations
        .AsExpandable()
        .Select(install => new DeviceInformation
        {
            Platform = deviceInfoPlatform.Invoke(install.Platform)
        });