DynamicExpresso : expression as variable

628 Views Asked by At

Let's assume we have a variable called TOTAL and it should be replaced with AProperty + BProperty of CClass. I have an IQueryrable set of CClass objects and I want to select (TOTAL + AProperty) from this set.

AProperty and BProperty are double values. I don't want to extend my class because it's an entity class in my DB and actually the TOTAL expression is a runtime, user defined variable. So I don't want to inject them by Reflection or some other solutions. I want to give capability to end user to declare some MACRO-liked variables to create more complicated expressions based on them.

Is there any way that I can define TOTAL expression for my interpreter according to above scenario?

1

There are 1 best solutions below

3
On

You wrote:

we have a variable called TOTAL and it should be replaced with...

Alas, LINQ is meant to select data from a sequence. LINQ won't change the input sequence.

Luckily you also wrote:

I have an IQueryrable set of CClass objects and I want to select (TOTAL + AProperty) from this set.

Okay, we can do that.

I don't want to change my class...

Of course you don't want to change your entity classes: your entity classes represent the tables in your database and the relations between those table. Your function is not something that is typically something of your database tables. Therefore it doesn't belong there.

So instead of changing your entity classes we'll write a separate extension function for your entities. For users of your class it would look as if the function is part of the class. See Extension Methods demystified

I won't write the function for your IQueryable<CClass>, I'll write a function for any queryable sequence of objects

Input: a queryable sequence of objects of some type and a double value Value.
Also: a> property selector that selects a get-property of your objects that has a double value.
Output: the sum of Value and the value of the get-property.

public static double AddToProperty<TSource> (this IEnumerable<TSource> source, 
     Expression<Func<TSource, double>> propertySelector,        
     double value);
     where Tsource : class
{
     return source.Select(soureElement => propertySelector(sourceElement) + value);
}

Usage:

var addedTotals = myDbContext.Students
    .AddToPropery( student => student.AnnualIncome, 3.14);