1

Is It possible to get the reference to the PositionViewModel in the following expression tree:

    public static Expression<Func<Model, ViewModel>> ToViewModel
    {
        get
        {
            return x => new PositionViewModel
            {
                Id = x.Id,
                Name = x.Name,
                Employees = x.Employees.Select(e => new Employee
                {
                    Id = e.Id,
                    Name = e.Name,
                    Position = ??? // reference to PositionViewModel
                }).ToList()
            };
        }
    }

I think it is, because EF does that. Any suggestions?

Edit: Forgot to mention that "Postition" is of type ViewModel.

user3049133
  • 229
  • 1
  • 4
  • 12
  • I don't think you can do it within the initializer syntax. – ta.speot.is Jan 15 '14 at 11:07
  • If `position==this` then initialize it in the constructor maybe? But this is an `Employee` object, why reference a `PositionViewModel`? I'm confused. – Lews Therin Jan 15 '14 at 11:09
  • I took the liberty of editing the question a bit to remove confusion. `this` refers to the current instance of the type in which the code is currently executing. The code in the question is in a static method (so, no current instance), and code wants a reference to another type. – Fredrik Mörk Jan 15 '14 at 11:17
  • When does the EF does that? Can't you just look at how how does it do it? – svick Jan 15 '14 at 13:38

2 Answers2

2

I would spontaneously do it in steps:

public static Expression<Func<Model, ViewModel>> ToViewModel
{
    get
    {
        return x => GetViewModel(x);
    }
}

public ViewModel GetViewModel(Model x)
{
    var vm = new PositionViewModel
    {
        Id = x.Id,
        Name = x.Name
    };

    vm.Employees = x.Employees.Select(p => new Employee
    {
        Id = p.Id,
        Name = p.Name,
        Position = vm
    }).ToList();

    return vm;
}

This way you can still wrap this up as an expression tree.

Fredrik Mörk
  • 155,851
  • 29
  • 291
  • 343
  • 1
    That was and my first tough, but this can't be an expression anymore. – user3049133 Jan 15 '14 at 11:16
  • http://stackoverflow.com/questions/9878184/object-and-collection-initializers-assign-self – theMayer Jan 15 '14 at 11:19
  • A lambda expression with a statement body cannot be converted to an expression tree. – user3049133 Jan 15 '14 at 11:21
  • @FredrikMörk Thanks. The problem is that if this is not a lambda expression it will leads to n + 1 syndrome. – user3049133 Jan 15 '14 at 11:29
  • @user3049133 See updated answer: by extracting the body into a separate method you can still keep the expression tree. – Fredrik Mörk Jan 15 '14 at 11:29
  • @FredrikMörk At first I want to say this is amazing idea! But LINQ to Entities doesn't like it. However, I think the problem is for another thread. Additional information: LINQ to Entities does not recognize the method 'ViewModel GetViewModel(Model)' method, and this method cannot be translated into a store expression. – user3049133 Jan 15 '14 at 11:36
  • @user3049133 You can't do that if you want to translate your expression to SQL. All of the code has to be an expression, not a simple expression that calls a method you wrote. – svick Jan 15 '14 at 13:37
1

What you could do is to use the fact that Employees is a property, so you can add any code you want to its setter. Something like:

private IList<Employee> employees;

public IList<Employee> Employees
{
    get
    {
        return employees;
    }

    set
    {
        employees = value;

        foreach (var employee in employees)
        {
            employee.Position = this;
        }
    }
}

With this, you don't need to do anything in your expression, and the Position will be set automatically.

svick
  • 236,525
  • 50
  • 385
  • 514
  • Thank you, your answer is more correct for my intentions. I wish I had the opportunity to mark two correct answers or at least to give you a plus. – user3049133 Jan 15 '14 at 19:12