Search code examples
c#entity-frameworkexpressionexpression-trees

EntityFramework - select entity with custom property projection


Consider following entity:

public class Model
{
    public int Id { get; set; }
    public decimal Value { get;  set; }
}

I'd like to round any decimal value before assigning to model instance. I'd could do it in this way:

dbContext.Models
             .Select(model => new 
                    { 
                      Id = model.Id, 
                      Value = Math.Round(model.Value, 10) 
                    }
             .ToList()
             .Select(anonymous => 
                          new Model 
                              { 
                                Id = anonymous.Id
                                Value = anonymous.Value
                              });

It works fine, but I've a entity that contains over 100 columns. Is it possible to build projection that automatically iterate throgh properties and call Math.Round on decimal properties and create entity model instance with new values?

I don't want implementation - only clue if it possible to do ith with expresion tree or should look for other solution.


Solution

  • Yes, you can certainly do this using expression trees. What I would do is to write a class that inherits from ExpressionVisitor, override its VisitMember() method and in there check for decimal properties. When you detect a decimal property, return that property wrapped in Math.Round().

    The end result should be exactly what you want: a lambda expression like model => new { Id = model.Id, Value = model.Value } will be transformed into model => new { Id = model.Id, Value = Math.Round(model.Value, 10) }. You can then call this from an extension method called something like SelectRounded().