我想做以下
public async Task<List<dynamic>> searchEntities(string query, list<string> columnNames)
{
var columNames = GetPropertiesUsingReflectionAndfilter<Entity>(columnNames);
await db.entities.select(x => { columnNames }).where(...)..ToListAsync();
}
我需要在Controller中公开自定义EF搜索方法。我想提供部分回应。 $ search在我正在使用的OData版本中无效。
这可能与IQueryable有关吗?
替代方案是构建参数化SQL查询。想知道是否有更好的方式使用EF和Linq?感谢..
解决方案:
感谢@IvanStoev,我最终添加了一个库,System.Linq.Dynamic (免费下载> 100万次),以实现这一目标。我现在有。
using System.Linq.Dynamic;
var columnNames = GetColumNames<Entity>(qry.TableList);
var selector = "new(" + String.Join(", ", columnNames.ToArray()) + ")";
var results = await db.Lessons
.Where(x => x.LessonName.Contains(qry.Query) == true || x.HTML.Contains(qry.Query) == true)
.Select(selector)
.ToListAsync();
return Ok(results);
TLDR。完全用于我的方案。
控制器:
[HttpPost, Route("Search/Lessons")]
public async Task<IHttpActionResult> SearchLessons([FromBody] SearchQuery qry)
{
var columnNames = GetColumNames<Lesson>(qry.TableList);
if (columnNames.Count < 1) {
return BadRequest();
}
var selector = "new(" + String.Join(", ", columnNames.ToArray()) + ")";
var results = await db.Lessons
.Where(x => x.LessonName.Contains(qry.Query) == true || x.HTML.Contains(qry.Query) == true)
.Select(selector)
.ToListAsync();
return Ok(results);
}
和助手:..
private List<string> GetColumNames<T>(List<string> columnsToFetch = null)
{
var properties = GetProperties<T>();
var columnNames = new List<string>();
if (columnsToFetch == null)
{
return properties;
}
foreach (var columnRequested in columnsToFetch)
{
var matchedColumn = properties
.Where(x => x.ToLower() == columnRequested.ToLower())
.FirstOrDefault();
if (matchedColumn != default(string))
{
columnNames.Add(matchedColumn);
}
}
return columnNames;
}
和..
private List<string> GetProperties<T>()
{
dynamic model = TypeDescriptor.GetProperties(Activator.CreateInstance<T>());
List<string> result = new List<string>();
foreach (var prop in model)
{
result.Add(prop.Name);
}
return result;
}
答案 0 :(得分:1)
免责声明:我是该项目的所有者Eval-Expression.NET
这个库不是免费的,但允许你编译&amp;在运行时执行C#代码。例如,您可以动态执行任何LINQ
教程:LINQ Dynamic
示例:
Server server = new Server();
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
server.save();
}
}));
server.listen();
答案 1 :(得分:0)
我看不出那是可能的。
首先,要从searchEntities返回列表,select需要创建一个命名对象。
您可以做的是将函数表达式传递给searchEntities
public Task<List<T>> searchEntities<T>(EXpression<Func<Entity, T> selector)
{
return await db.entities.select(selector).where(...)..ToListAsync();
}
Expression<Func<Entity, AdHocClass1> selector1 = (Entity e)=> new AdHocClass1 {...};