动态linq查询与动态条件和条件

时间:2013-01-27 16:06:31

标签: linq entity-framework ef-code-first

public GetApplicants(string Office,
                         int Id,
                         List<int> cfrparts,
                         List<int> expertiseAreaIds,
                         List<int> authIds,
                         List<int> specIds)
    {
        bool isAuthIdsNull = authIds == null;
        authIds = authIds ?? new List<int>();
        bool isSpecIdNull = specIds == null;

enter code here
     var query =
            from application in Apps
            from cfr in application.cfr
            from exp in cfr.Aoe
           from auth in exp.Auth
            from spec in exp.Special

            where application.Design.Id == 14
            where  (iscfrpart || cfrPartIds.Contains(cfr.CfrP.Id))
            where (isexp || expertiseAreaIds.Contains(exp.Aoe.Id))
            where (isAuthIdsNull || authIds.Contains(auth.Auth.Id))
            where  (isSpecIdNull || specIds.Contains(spec.Special.Id))
            where application.Office.Text.Contains(Office)
            where application.D.Id == Id

            select application.Id;

如何使此查询动态化。如果我只有Id和Office值,它仍然应该根据可用值给我结果集。当然它没有给我结果。

2 个答案:

答案 0 :(得分:1)

使用where

,而不是对&&进行多次调用
 var query =
        from Apps
        where (iscfrpart || cfrPartIds.Contains(Apps.cfr.CfrP.Id))
        && (isexp || expertiseAreaIds.Contains(Apps.cfr.Aoe.Id))
        && (isAuthIdsNull || authIds.Contains(Apps.cfr.Aoe.Auth.Id))
        && (isSpecIdNull || specIds.Contains(Apps.cfr.Aoe.Special.Id))
        && Apps.Office.Text.Contains(Office)
        && Apps.D.Id == Id

        select application.Id;

此外,如果传入的Id不等于14,则此子句application.D.Id == 14与此结合后将导致0结果:application.D.Id == Id。您可能希望删除该第一个子句。

编辑:更新了您的from子句,但我仍然认为这不会起作用,因为您的表结构似乎已关闭。

答案 1 :(得分:0)

解决此问题不需要动态查询。您可以编写构造查询的代码。

根据您拥有的信息制作一个构建过滤器的方法。

public Expression<Func<Application, bool>> GetFilterForCFR(List<int> cfrParts)
{
  if (cfrParts == null || !cfrParts.Any())
  {
    return app => true;
  }
  else
  {
    return app => app.cfr.Any(cfr => cfrParts.Contains(cfr.cfrPId));
  }
}

然后,您可以使用表达式构建查询。

var query = Apps;
var cfrFilter = GetFilterForCFR(cfrParts);
query = query.Where(cfrFilter);

//TODO apply the other filters

var finalquery = query.Select(app => app.Id);