Search code examples
c#asp.net-mvcentity-frameworklinqkendo-asp.net-mvc

System.Linq.Expressions with computed column


In the MVC project I'm working I have a kendo dropDownList that calls my server Action to execute any read operation (including filtering):

ServiceRequestAssociabili([DataSourceRequest] DataSourceRequest request, int? idServiceRequestOriginale)

The widget is bound to 2 properties: IdServiceRequest (value) and IdServiceRequestDescrizione(text).

IdServiceRequest is the Entity Id and IdServiceRequestDescrizione is a computed column which I have defined in the Partial class of the Entity

public string IdServiceRequestDescrizione
        {
            get
            {
                if (TipologiaChiamata.IdTipologiaChiamata != (int)Enums.TipologiaChiamata.Automatica)
                {
                    return IdServiceRequest + " " + Note;
                }
                else
                {
                    return IdServiceRequest + " " + Email.EmailOggetto;
                }
            }
        }

In order to create the correct linq query to execute the filter I created a System.Linq.Expression that translate my Entity to the DTO containing 2 string properties:

Expression<Func<ServiceRequest, DTO>> funcError = s => new DTO
            {
                IdServiceRequest = s.IdServiceRequest,
                IdServiceRequestDescrizione = s.IdServiceRequestDescrizione
            };

I then use this Expression to project my IQueryable:

var srq = _serviceRequestRepository.GetByParametersAsQueryable(idServiceRequestOriginale: idServiceRequestOriginale, senzaTicketAssociato: true).Select(funcError).ToList();            

When I materialize the query with ToList() the following error occurs:

enter image description here

If I instead of defining IdServiceRequestDescrizione in the partial I define it inside the System.Linq.Expression no error is thrown and everything works fine.

Expression<Func<ServiceRequest, DTO>> func = s => new DTO
            {
                IdServiceRequest = s.IdServiceRequest,
                IdServiceRequestDescrizione = s.TipologiaChiamata.IdTipologiaChiamata != (int)EntityModel.Enums.TipologiaChiamata.Automatica ? s.IdServiceRequest + " " + s.Note : s.IdServiceRequest + " " + s.Email.EmailOggetto
            };

Can somebody give me a professional explanation of this behavior? Why I can't reference a custom property in the linq Expression?


Solution

  • The computed column is implemented in C#, but EF only operates on the database model (translated to/from SQL).

    Your code should work if you reverse the order of method calls to

    .ToList().Select(funcError);
    

    i.e. the records are first translated into C# entity objects, and then computed columns are accessible. (I usually use NHibernate, but the issue is the same)