开发者

Problems with LINQ WhereClause

Many thanks to leppie: Currently I got

Expression<Func<vwMailMerge,bool>> whereClause= null;
List<vwMailMerge> mailMergeItems = null;

int personType = mailMergeSettings.PersonType.ToInteger();
if (personType > 0)
{
    whereClause = this.MailMergeWhereClause(whereClause, f => f.MemberTypeId == personType);
}
if (mailMergeSettings.PersonIds != null)
{
    var personIds = mailMergeSettings.PersonIds.ToGuidArray();
    if (personIds != null && personIds.Length > 0)
    {
        var personList = personIds.ToList();
        whereClause = this.MailMergeWhereClause(whereClause, f => personList.Contains(f.UserId));
    }
}开发者_JAVA百科

mailMergeItems = this.ObjectContext.vwMailMerges.Where(whereClause).ToList();
private Expression<Func<vwMailMerge, bool>> MailMergeWhereClause(params Expression<Func<vwMailMerge, bool>>[] wheres)
{
    if (wheres.Length == 0)
    {
        return x => true;
    }
    Expression result;   
    if (wheres[0] == null)
    {
        result = wheres[1].Body;
        return Expression.Lambda<Func<vwMailMerge, bool>>(result, wheres[1].Parameters);
    }
    else
    {
        result = wheres[0].Body;
        for (int i = 1; i < wheres.Length; i++)
        {
            result = Expression.And(result, wheres[i].Body);
        }
        return Expression.Lambda<Func<vwMailMerge, bool>>(result, wheres[0].Parameters);
        }     
    }
}

When it gets to "mailMergeItems =" it drops and gives error: "The parameter 'f' was not bound in the specified LINQ to Entities query expression."

I've noticed that when checking only for people, or only for membertypeId, it works properly.. but combined the 2nd gives a error on it's "f=>" I think.


You cant use Func, you need to use Expression<Func>.

The + can be done via Expression.And.

Update (not tested):

Expression<Func<vwMailMerge, bool>> whereClause = null;
...
Expression<Func<vwMailMerge, bool>> MailMergeWhereClause(
   params Expression<Func<vwMailMerge, bool>>[] wheres)
{
  if (wheres.Length == 0) return x => true;
  Expression result = wheres[0].Body;
  for (int i = 1; i < wheres.Length; i++)
  {
    //probaby needs a parameter fixup, exercise for reader
    result = Expression.And(result, wheres[i].Body); 
  }
  return Expression.Lambda<Func<vwMailMerge,bool>>(result, wheres[0].Parameters);
}

Update 2:

The above approach fails as I expected. It might be easy to solve on .NET 4 using the ExpressionVistor class. For .NET 3.5 (or if aforementioned is too hard) the following should work.

The approach is the append the where clauses in the IQueryable directly so you end up with:

somequery.Where(x => x.foo).Where(x => x.bar).Where(x => x.baz)

IOW, you can just add them as required, but it will require some changes to the logic/flow of the code you pasted.


You could reformat your question better with the code tool.

However it looks like you could approach the problem in this way to avoid all those func expressions floating around:

this.ObjectContext.vwMailMerges.Where(mm=>IsValidMailMerge(mm,personType)).ToList()


private bool IsValidMailMerge(YourType mailmerge, YourType2 personType)
{
if(...) // type specific criteria here
return true;
else
return false;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜