Search code examples
vb.netlinqentity-frameworkworkflow-foundation-4

LINQ to Entities does not recognize the method [Type] GetValue[Type]


enter image description hereI've a simple class like this:

Public Class CalculationParameter{
    public Long TariffId{get;set;}
}

In a workflow activity, I've an Assign like this:

(From tariffDetail In db.Context.TariffDetails
Where tariffDetial.TariffId = calculationParameter.TariffId).FirstOrDefault()

Dto is passed to Activity as an Input Argument.

It raise following error and I'm wondering how to assign Id. Any Idea?

LINQ to Entities does not recognize the method 'Int64 GetValue[Int64](System.Activities.LocationReference)' method, and this method cannot be translated into a store expression.

How can I assign the calculationParameter.TariffId to tariffDetial.TariffId?!

UPDATE: Screen shot attached shows that how I'm trying to assign calculationParameter.TariffId to tariffDetail.TariffId (car.Id = Dto.Id) and the query result should assign to CurrentTrafficDetail object.


Solution

  • Here's your problem. I don't know if there is a solution to it.

    As you said in a (now deleted, unfortunately necessitating that I answer) comment, the exception you're getting is

    LINQ to Entities does not recognize the method Int64 GetValue[Int64](System.Activities.LocationReference) method, and this method cannot be translated into a store expression.

    in your Linq query, calculationParameter is a Variable defined on the workflow. That Variable is actually an instance that extends the type System.Activities.LocationReference and NOT CalculationParameter.

    Normally, when the workflow executes, the LocationReference holds all the information it needs to find the value which is assigned to it. That value isn't retrieved until the last possible moment. At runtime, the process of retrieval (getting the executing context, getting the value, converting it to the expected type) is managed by the workflow.

    However, when you introduce Linq into the mix, we have the issue you are experiencing. As you may or may not know, your expression gets compiled into the extension method version of the same.

    (From tariffDetail In db.Context.TariffDetails  
    Where tariffDetial.TariffId = calculationParameter.TariffId)
    .FirstOrDefault()
    

    is compiled to

    db.Context.TariffDetails
              .Where(x => x.TariffId = calculationParameter.TariffId)
              .FirstOrDefault();
    

    When this executes, L2E doesn't actually execute this code. It gets interpreted and converted into a SQL query which is executed against the database.

    As the interpreter isn't omniscient, there are a well defined set of limitations on what methods you can use in a L2S query.

    Unfortunately for you, getting the current value of a LocationReference is not one of them.

    TL:DR You cannot do this.

    As for workarounds, the only thing I think you can do is create a series of extension methods on your data context type or add methods to your CalculationParameter class that you can call from within the Expression Editor. You can create your Linq to Entities queries within these methods, as all types will already have been dereferenced by the workflow runtime, which means you won't have to worry about the L2E interpreter choking on LocationReferences.

    *Edit: A workaround can be found here (thanks to Slauma who mentioned this in a comment on the question)