2

My learning of expression is really basic, I have the following function predicate

Func<RecordViewModel, Func<ReportModel, bool>> exp = rec => x => x.Firstname == rec.Firstname &&
                                                                 x.Surname == rec.Surname;

var func = exp(new RecordViewModel() { Firstname= "Peter", Surname  = "Jones" });

The Following are my model and viewmodel,

public class ReportModel
{
    public string Firstname { get; set; }
    public string Surname { get; set; }
}
public class RecordViewModel
{
    public string Firstname { get; set; }
    public string Surname { get; set; }
}

I would like to get the expression serialized to ((ReportModel.Firstname == "Peter") AndAlso (ReportModel.Surname == "Jones")).

Any help of this is greatly appreciated,

krillgar
  • 12,596
  • 6
  • 50
  • 86
Jyothish
  • 541
  • 2
  • 5
  • 25

2 Answers2

0

If you want to return a string, this should be your expression:

Func<RecordViewModel, string> exp = rec (x) => return x.Firstname == rec.Firstname &&
         x.Surname == rec.Surname ? "ReportModel.Firstname" + x.Firstname + " " 
         + "ReportModel.Surname" + " "  rec.Surname : string.empty;

Then you can call the expression by passin the Model:

var func = exp(new RecordViewModel() { Firstname= "Peter", Surname  = "Jones" });
Willy David Jr
  • 8,604
  • 6
  • 46
  • 57
0

So, if I understood you correctly you was given a Func (called exp in your example) and you need to provide a toString method for it.

You can use something like this:

Func<Func<ReportModel, bool>, string> toString = func => 
{
    var vm = ((dynamic)func.Target).rec;
    var paramType = func.Method.GetParameters()[0].ParameterType;
    var firstNameProperty = paramType.GetProperties().First(p => p.Name == nameof(vm.Firstname)).Name;
    var surnameProperty = paramType.GetProperties().First(p => p.Name == nameof(vm.Surname)).Name;
    return $"(({paramType.Name}.{firstNameProperty} == \"{vm.Firstname}\") AndAlso ({paramType.Name}.{surnameProperty} == \"{vm.Surname}\"))";
};

Console.WriteLine(toString(exp(viewModel))); 
//returns ((ReportModel.Firstname == "Peter") AndAlso (ReportModel.Surname == "Jones"))

In there you use a bit of reflection to get the parameters (and you know that there is always 1 of them) of your func to make the comparison. And you look for properties of that parameter based on name.

There is also a small trick with dynamic to get the rec value (your RecordViewModel). It can be dirty, but if it works...

And, obviously, you also hardcode the representation of your resulting string.

JleruOHeP
  • 10,106
  • 3
  • 45
  • 71