根据请求对象属性动态构建查询

时间:2018-10-31 14:38:55

标签: c# entity-framework

我有一个Web应用程序,用户可以根据某些过滤条件从数据库中获取记录。他们可以获取所有记录,或两个日期之间的所有记录,或特定实体类型的所有记录,或特定用户的所有记录等。我正在使用EF6和仅标准的DbContext类来查询数据库

我想做的是基于请求对象和哪些属性不为null来动态构建查询。因此,如果用户选择起始日期和截止日期,但没有其他条件,则查询应转到数据库并获取所述日期之间的所有记录。如果用户未选择日期而是实体类型,则查询应仅基于请求对象的属性进行过滤。

所以在伪代码中,构建查询时我该怎么做

  • 检查所有请求对象属性
  • 所有属性都不为空,请将其作为参数添加到查询表达式中

这是我的请求对象

public class ChangeLogRequestDto
{
    public DateTime? FromDate { get; set; }
    public DateTime? ToDate { get; set; }
    public string UserName { get; set; }
    public string CallCenter { get; set; }
    public string EntityType { get; set; }
    public string PropertyName { get; set; }
    public string CompanyId { get; set; }
}

这是我的Service方法,用于接收此请求对象并构建查询以获取记录

 public IEnumerable<ChangeLog> GetChangeLogWithFilter(ChangeLogRequest request)
    {
       // check the request object and build a query based on its values.
       return dbContext.ChangeLogs.Where(query)
    }

我查找了其他示例,但由于我对Expressions和Linq不熟悉,因此对我来说没有意义。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

这是我将如何执行此操作的示例(基于我认为您正在尝试执行的操作)

public IEnumerable<ChangeLog> GetChangeLogWithFilter(ChangeLogRequest request)
{
   var query = dbContext.ChangeLogs;
   if(request.FromDate != null && request.ToDate != null)
   {
      query = query.Where(x => x.DateSubmitted > request.FromDate && x.DateSubmitted <= request.ToDate);
   }

   if(!string.IsNullOrEmpty(request.UserName))
   {
      query = query.Where(x => x.UserName.Equals(request.UserName));
   }
   // then you repeat the above with the rest of the values if they are available
   return query.ToList();
}

希望这能解决您的用例。建立查询的方法有更高级的方法,例如表达式树,但是我认为对于上述要求,您应该可以解决。

答案 1 :(得分:0)

您好,德尔,我强烈建议您使用OData(开放数据协议)之类的标准模式:

这将使您能够对OData端点执行动态查询,例如访问元素详细信息,对列表进行排序以及应用所需的过滤器,所有这些都直接从HTTP请求中进行。

希望它会有所帮助,如果您需要任何其他帮助或说明,请告诉我