gpt4 book ai didi

c# - 进行通用 MVC API 查询

转载 作者:行者123 更新时间:2023-11-30 15:58:38 25 4
gpt4 key购买 nike

我正在 .NET Core 中构建 MVC API。我有几个非常大的表(第 3 方系统),我试图允许将任何列的名称作为 URL 参数传递,并在 Where 子句中使用一个值。这使用 Entity Framework 和 .NET Core。

想法是抓取与参数名称匹配的列,并在带有参数值的 Where 子句中使用它。我希望 Where 查询中的 lambda 最终看起来像:

//GET: api/DWRWorkItems?Parameter=Value
...
dWRWorkItem = dWRWorkItem.Where(m =>
m.Parameter == Value
);

这是我尝试的一个干净的解决方案,来自 Controller 的路由代码。模型和 View 与 Entity Framework 创建的默认值没有变化。

    // GET: api/DWRWorkItems
[HttpGet]
public IEnumerable<DWRWorkItem> GetTDwrWrkItm()
{
IQueryable<DWRWorkItem> dWRWorkItem = _context.TDwrWrkItm.Where(m => 1 == 1);
var q = HttpContext.Request.Query;
foreach (string p in q.Keys)
{

dWRWorkItem = dWRWorkItem.Where(m =>
m.GetType().GetProperty(p).GetValue(m, null) == q[p]
);

}

return dWRWorkItem.ToList();
}

Intellisense (VS 2017) 预计不会出现错误,但是当我运行它时,我得到:

The operands for operator 'Equal' do not match the parameters of method 'op_Equality'.

单步执行代码,lambda 中的反射似乎没有按预期工作。这是 dWRWorkItem.Expression.Arguments[1] 的样子:

{m => (GetProperty(m.GetType(), value(EBOOKS.Controllers.DWRWorkItemsController+<>c__DisplayClass0#1).p).GetValue(m, null) == value(EBOOKS.Controllers.DWRWorkItemsController+<>c__DisplayClass0#1).CS$<>8__locals1.q.get_Item(value(EBOOKS.Controllers.DWRWorkItemsController+<>c__DisplayClass0#1).p))}

虽然参数不是动态的示例如下所示:

{m => (m.ContId == value(EBOOKS.Controllers.DWRWorkItemsController+<>c__DisplayClass3_0).id)}

最佳答案

一般来说,除 LINQ to Objects 之外的查询提供程序不喜欢表达式树内部的反射调用,因此最好使用 System.Linq.Expressions.Expression 动态组合表达式类方法。

这是适合您的情况的自定义扩展方法:

public static partial class QueryableExtensions
{
public static IQueryable<T> WhereEquals<T>(this IQueryable<T> source, string memberPath, string value)
{
var parameter = Expression.Parameter(typeof(T), "e");
var left = memberPath.Split('.').Aggregate((Expression)parameter, Expression.PropertyOrField);
var right = Expression.Constant(ToType(value, left.Type), left.Type);
var predicate = Expression.Lambda<Func<T, bool>>(Expression.Equal(left, right), parameter);
return source.Where(predicate);
}

private static object ToType(string value, Type type)
{
if (type == typeof(string)) return value;
if (string.IsNullOrEmpty(value)) return null;
return Convert.ChangeType(value, Nullable.GetUnderlyingType(type) ?? type);
}
}

除了使用 Expression.Equal(相当于 == 运算符)之外,它还必须将 string 处理为实际值类型转换,顺便说一句,这是你原来的异常的原因。

用法是这样的:

var dWRWorkItem = _context.TDwrWrkItm.AsQueryable();
var q = HttpContext.Request.Query;
foreach (string p in q.Keys)
dWRWorkItem = dWRWorkItem.WhereEquals(p, q[p]);
return dWRWorkItem.ToList();

关于c# - 进行通用 MVC API 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42935150/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com