title: Convert a method to linq to entities expression for query the entity framework
body: <p>I have this problem and I really don't know how to solve it. I asked two questions before abput this problem but didn't get to figure the right answer for my situation. Here is the problem in details.
  I have an interface and default implementation:</p>
  
  <pre><code>public interface IEntityPriceDefinition
  {
      PriceDefinition PriceDefinition { get; }
  
      bool IsMatch(long additionId);
  
      bool IsMatch(long? entityId, long? inviterId, long? routeId, long? luggageTypeId);
  
      bool IsMatch(long? entityId, long? inviterId, long? routeId, long? luggageTypeId,
          long additionId);
  
      bool IsMatch(long? entityId, Task3 task);
  
      bool IsMatch(long? entityId, Task3 task, long additionId);
  }
  
  public class EntityPriceDefinition : IEntityPriceDefinition
      {
          private PriceDefinition _PriceDefinition;
          private Func&lt;long?, bool&gt; _IsEntityIdMatch;
          private Func&lt;Task3, long?&gt; _TaskValue;
  
          public PriceDefinition PriceDefinition { get { return _PriceDefinition; } }
  
          internal EntityPriceDefinition(
              PriceDefinition priceDefinition,
              Func&lt;long?, bool&gt; isEntityIdMatch,
              Func&lt;Task3, long?&gt; taskValue)
          {
              _PriceDefinition = priceDefinition;
              _IsEntityIdMatch = isEntityIdMatch;
              _TaskValue = taskValue;
          }
  
          public bool IsMatch(long additionId)
          {
              return PriceDefinition.AdditionsPrices.Any(x =&gt; x.AdditionId == additionId);
          }
  
          private bool IsMatch(long? inviterId, long? routeId, long? luggageTypeId)
          {
              bool isMatch = inviterId.HasValue || routeId.HasValue || luggageTypeId.HasValue;
              if (isMatch)
              {
                  if (PriceDefinition.InviterId.HasValue &amp;&amp; inviterId.HasValue)
                  {
                      if (PriceDefinition.InviterId.Value != inviterId.Value) { isMatch = false; }
                  }
                  if (PriceDefinition.LuggageTypeId.HasValue &amp;&amp; luggageTypeId.HasValue)
                  {
                      if (PriceDefinition.LuggageTypeId.Value != luggageTypeId.Value) { isMatch = false; }
                  }
                  if (PriceDefinition.RouteId.HasValue &amp;&amp; routeId.HasValue)
                  {
                      if (PriceDefinition.RouteId.Value != routeId.Value) { isMatch = false; }
                  }
              }
              return isMatch;
          }
  
          public bool IsMatch(long? entityId, long? inviterId, long? routeId, long? luggageTypeId)
          {
              return _IsEntityIdMatch(entityId) &amp;&amp; IsMatch(inviterId, routeId, luggageTypeId);
          }
  
          public bool IsMatch(long? entityId, long? inviterId, long? routeId, long? luggageTypeId,
              long additionId)
          {
              return IsMatch(entityId, inviterId, routeId, luggageTypeId) &amp;&amp; IsMatch(additionId);
          }
  
          public bool IsMatch(long? entityId, Task3 task)
          {
              bool isMatch = _IsEntityIdMatch(_TaskValue(task)) &amp;&amp;
                  IsMatch(task.InviterId, task.RouteId, task.LuggageTypeId);
  
              for (int i = 0; i &lt; PriceDefinition.Rules.Count &amp;&amp; isMatch == true; i++)
              {
                  object value = task.GetFieldObjectValue(PriceDefinition.Rules[i].FieldName);
                  isMatch = PriceDefinition.Rules[i].IsMatch((value ?? string.Empty).ToString());
              }
              return isMatch;
          }
  
          public bool IsMatch(long? entityId, Task3 task, long additionId)
          {
              return IsMatch(entityId ,task) &amp;&amp; IsMatch(additionId);
          }
      }
  </code></pre>
  
  <p>I also have 3 classes that implement <code>IEntityPriceDefinition</code> using the default implementation. Here are two of those classes (the third is the same):</p>
  
  <pre><code>public class CustomerPriceDefinition : IEntityPriceDefinition, IDataEntity
      {
          private IEntityPriceDefinition _EntityPriceDefinition;
  
          public virtual long PriceDefinitionId { get; set; }
          public virtual long CustomerId { get; set; }
          public virtual PriceDefinition PriceDefinition { get; set; }
  
          public CustomerPriceDefinition()
          {
              _EntityPriceDefinition = new EntityPriceDefinition(
                  PriceDefinition,
                  entityId =&gt; entityId.HasValue &amp;&amp; entityId.Value == CustomerId,
                  t =&gt; t.CustomerId);
          }
  
          public bool IsMatch(long additionId)
          {
              return _EntityPriceDefinition.IsMatch(additionId);
          }
  
          public bool IsMatch(long? customerId, long? inviterId, long? routeId, long? luggageTypeId)
          {
              return _EntityPriceDefinition.IsMatch(customerId, inviterId, routeId, luggageTypeId);
          }
  
          public bool IsMatch(long? customerId, long? inviterId, long? routeId, long? luggageTypeId,
              long additionId)
          {
              return _EntityPriceDefinition.IsMatch(customerId, inviterId, routeId, luggageTypeId,
                  additionId);
          }
  
          public bool IsMatch(long? customerId, Task3 task)
          {
              return _EntityPriceDefinition.IsMatch(customerId, task);
          }
  
          public bool IsMatch(long? customerId, Task3 task, long additionId)
          {
              return _EntityPriceDefinition.IsMatch(customerId, task, additionId);
          }
      }
  
  public class WorkerPriceDefinition : IEntityPriceDefinition, IDataEntity
      {
          private IEntityPriceDefinition _EntityPriceDefinition;
  
          public virtual long PriceDefinitionId { get; set; }
          public virtual long WorkerId { get; set; }
          public virtual PriceDefinition PriceDefinition { get; set; }
  
          public WorkerPriceDefinition()
          {
              _EntityPriceDefinition = new EntityPriceDefinition(
                  PriceDefinition,
                  entityId =&gt; entityId.HasValue &amp;&amp; entityId.Value == WorkerId,
                  t =&gt; t.WorkerId);
          }
  
          public bool IsMatch(long additionId)
          {
              return _EntityPriceDefinition.IsMatch(additionId);
          }
  
          public bool IsMatch(long? workerId, long? inviterId, long? routeId, long? luggageTypeId)
          {
              return _EntityPriceDefinition.IsMatch(workerId, inviterId, routeId, luggageTypeId);
          }
  
          public bool IsMatch(long? workerId, long? inviterId, long? routeId, long? luggageTypeId,
              long additionId)
          {
              return _EntityPriceDefinition.IsMatch(workerId, inviterId, routeId, luggageTypeId,
                  additionId);
          }
  
          public bool IsMatch(long? workerId, Task3 task)
          {
              return _EntityPriceDefinition.IsMatch(workerId, task);
          }
  
          public bool IsMatch(long? workerId, Task3 task, long additionId)
          {
              return _EntityPriceDefinition.IsMatch(workerId, task, additionId);
          }
      }
  </code></pre>
  
  <p>I have also repository interface and default implementation for those classes:</p>
  
  <pre><code>public interface IEntityPriceDefinitionRepository&lt;T&gt; : IRepository&lt;T&gt;
      where T : class, IEntityPriceDefinition, IDataEntity
  {
      IEnumerable&lt;T&gt; GetMatchPrices(
          Guid companyId, bool? isSuggested, bool? isValid,
          long? entityId, long? inviterId, long? routeId, long? luggageTypeId,
          Func&lt;IQueryable&lt;T&gt;, IOrderedQueryable&lt;T&gt;&gt; orderBy,
          Expression&lt;Func&lt;T, object&gt;&gt;[] includes);
  
      IEnumerable&lt;T&gt; GetMatchPrices(
          Guid companyId, bool? isSuggested, bool? isValid,
          long? entityId, long? inviterId, long? routeId, long? luggageTypeId, long additionId,
          Func&lt;IQueryable&lt;T&gt;, IOrderedQueryable&lt;T&gt;&gt; orderBy,
          Expression&lt;Func&lt;T, object&gt;&gt;[] includes);
  }
  
  public class EntityPriceDefinitionRepository&lt;T&gt; : BaseRepository&lt;T&gt;,
      IEntityPriceDefinitionRepository&lt;T&gt; where T : class,IEntityPriceDefinition, IDataEntity
  {
      private IEnumerable&lt;T&gt; GetMatchPrices(
          Guid companyId, bool? isSuggested, bool? isValid,
          Expression&lt;Func&lt;T, bool&gt;&gt; isMatch,
          Func&lt;IQueryable&lt;T&gt;, IOrderedQueryable&lt;T&gt;&gt; orderBy,
          Expression&lt;Func&lt;T, object&gt;&gt;[] includes)
      {
          var filters = new Expression&lt;Func&lt;T, bool&gt;&gt;[]{
              x =&gt; x.PriceDefinition.CompanyId == companyId,
              x =&gt; x.PriceDefinition.IsDeleted == false,
              x =&gt; !isValid.HasValue || x.PriceDefinition.IsValid == isValid.Value,
              x =&gt; !isSuggested.HasValue || x.PriceDefinition.IsSuggested == isSuggested.Value,
              isMatch
          };
  
          return GetQuery(filters, orderBy, includes);
      }
  
      public IEnumerable&lt;T&gt; GetMatchPrices(
          Guid companyId, bool? isSuggested, bool? isValid,
          long? entityId, long? inviterId, long? routeId, long? luggageTypeId,
          Func&lt;IQueryable&lt;T&gt;, IOrderedQueryable&lt;T&gt;&gt; orderBy,
          Expression&lt;Func&lt;T, object&gt;&gt;[] includes)
      {
          return GetMatchPrices(companyId, isSuggested, isValid,
          //////////////////  THIS CAUSE THE EXCEPTION MENTIONED BELOW:  //////////////////
              x =&gt; x.IsMatch(entityId, inviterId, routeId, luggageTypeId),
              orderBy, includes);
      }
  
      public IEnumerable&lt;T&gt; GetMatchPrices(
          Guid companyId, bool? isSuggested, bool? isValid,
          long? entityId, long? inviterId, long? routeId, long? luggageTypeId, long additionId,
          Func&lt;IQueryable&lt;T&gt;, IOrderedQueryable&lt;T&gt;&gt; orderBy,
          Expression&lt;Func&lt;T, object&gt;&gt;[] includes)
      {
          return GetMatchPrices(companyId, isSuggested, isValid,
          //////////////////  THIS CAUSE THE EXCEPTION MENTIONED BELOW:  //////////////////
              x =&gt; x.IsMatch(entityId, inviterId, routeId, luggageTypeId, additionId),
              orderBy, includes);
      }        
  }
  </code></pre>
  
  <p>And the classes repository classes are just:</p>
  
  <pre><code> public class CustomerPriceDefinitionRepository :
          EntityPriceDefinitionRepository&lt;CustomerPriceDefinition&gt; { }
  
      public class WorkerPriceDefinitionRepository :
          EntityPriceDefinitionRepository&lt;WorkerPriceDefinition&gt; { }
  </code></pre>
  
  <p>The problem happend when I call CustomerPriceDefinitionRepository's GetMatchPrices method. It always ends up with exception about the method that marked above:</p>
  
  <blockquote>
    <p>LINQ to Entities does not recognize the method 'Boolean IsMatch(System.Nullable<code>1[System.Int64], System.Nullable</code>1[System.Int64], System.Nullable<code>1[System.Int64], System.Nullable</code>1[System.Int64])' method, and this method cannot be translated into a store expression.</p>
  </blockquote>
  
  <p>Ladislav Mrnka's answered me <a href="https://stackoverflow.com/questions/5845993/linq-to-entities-doesnt-recognize-a-method/5847323#5847323">here</a> to use model defined functions but I want all my code to be in its classes and not in xml's. In addition, this code doesn't relevant to the huge scope that the edmx uses. In addition, I believe that in order to use model defined functions I will have to define 3 methods - one IsMatch for each sub class of IEntityPriceDefinition.</p>
  
  <p>I really don't know how to solve this problem and what is the best solution for such case especially for such non-simple structure. I will appriciate any help.</p>