【发布时间】:2018-01-23 18:33:26
【问题描述】:
我有一个表格来记录我希望围绕这些协议构建 Web API 的协议。我希望能够使用 GET 方法来搜索表格。但是,我希望参数是可选的。例如,如果我使用 GET 调用并指定 Date == 1/23/2018 以及 Status == Active 我希望它返回所有符合即使其他可能的参数可能等于 null。
我正在使用控制器上的绑定从需要类似协议的对象的 Uri 中提取。这只是 Table Agreement 的数据上下文。我已经能够让它工作了。问题与查询有关。如果用户只指定两个变量,则其余参数设置为空。
如何编写 linq to SQL 查询,以便只使用非空参数进行查询?解析可能的参数然后从非空值构建查询的效果。
注意:我不希望客户端必须为所有参数指定一个值。只是与它们相关的那些,然后让控制器/服务类对其进行排序。
控制器
namespace API.Controllers
{
public class AgreementsController : ApiController
{
private AgreementRepository agreementRepository;
public AgreementsController()
{
this.agreementRepository = new AgreementRepository();
}
public AGREEMENT[] Get([FromUri]AGREEMENT Agreement)
{
return agreementRepository.GetAgreement(Agreement);
}
}
}
服务
namespace API.Services
{
public class AgreementRepository
{
private DatabaseEntities db = new DatabaseEntities();
public AGREEMENT[] GetAgreement(AGREEMENT agmt)
{
var query = from a in db.AGREEMENTS select a;
query.Where(a => ??????);
AGREEMENT[] agreements = query.ToArray<AGREEMENT>();
return agreements;
}
}
}
编辑 我想找到一种避免硬编码参数值的方法,并且宁愿根据可用参数动态构建查询。这样,对表和/或数据上下文的更改将直接反映并由该代码适当地处理。
编辑 2 我已经尝试使用反射来构建字典并尝试通过遍历字典来动态构建查询。下面的查询似乎无效,因为正在返回每个协议。
public AGREEMENT[] GetAgreement(AGREEMENT agmt)
{
Type type = agmt.GetType();
PropertyInfo[] properties = type.GetProperties();
Dictionary<string, object> propDictionary = new Dictionary<string, object>();
foreach (PropertyInfo property in properties)
{
var propertyValue = property.GetValue(agmt, null);
if (propertyValue != null)
{
propDictionary.Add(property.Name, propertyValue);
}
}
var query = from a in db.AGREEMENTS select a;
foreach (var prop in propDictionary)
{
query.Where(A => A.GetType().GetProperty(prop.Key).GetValue(A,null) == prop.Value);
}
AGREEMENT[] agreements = query.ToArray<AGREEMENT>();
return agreements;
}
【问题讨论】:
-
如果您实际上将
query.Where(...)的结果保存回query,您的反射解决方案是否有效? -
您可以在运行时使用
Expression的方法创建查询。 但是请记住,在现实世界的应用程序中,每个字段的标准可能不同,例如对于字符串属性您可能需要StartsWith,对于另一个您可能需要Contains,对于一个 int 属性,您可能需要使用>=和/或<=的范围,对于另一个 int 属性,您可能需要检查确切的值等等。 -
与其尝试编写通用逻辑,不如考虑创建特定的搜索逻辑。你可以在周围看到很好的例子,例如:Filter/Search using Multiple Fields - ASP.NET MVC 或 Filtering the data at the controller before it is rendered in a view。
标签: c# asp.net linq rest asp.net-web-api