我仍在完全学习和理解实体框架,但正在致力于一个个人项目,旨在增加学习。
目前我有一个搜索功能,可以搜索艺术家、专辑或标题(或任意三者的组合)。
为了简化我在此处添加的代码量,我有一个带有复选框的 Angular UI,然后将其推送到 Web API。我已经检查了模型 Web API 端,收到的数据是正确的。
我想做的是查询SQL表,在表列中:
当[Artist]
为
SearchTerm
时,列
Artist
包含
true
或
当[Album]
为
SearchTerm
时,列
Album
包含
true
或
当[Title]
为
SearchTerm
时,列
Title
包含
true
将结果查询集输出回 Angular UI。
我已经尝试使用下面的代码进行此操作,但我认为我首先通过
Artist
缩小范围,然后无论修剪下来的数据集是什么,然后通过Album
进行过滤,最后通过Title
进行过滤,因此通常不会返回任何记录,因为条件会删除使用 OR 条件找到的潜在搜索值。
SearchModel.cs
namespace Project.Models
{
public class SearchModel
{
public string SearchTerm { get; set; } = string.Empty;
public bool Artist { get; set; }
public bool Album { get; set; }
public bool Title { get; set; }
}
}
SearchController.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Project.Context;
using Project.Models;
namespace Project.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class SearchController : ControllerBase
{
private readonly AppDbContext _db;
public SearchController(AppDbContext db)
{
this._db = db;
}
[Authorize]
[HttpPost]
public async Task<ActionResult<TrackData>> SearchAll([FromBody] SearchModel searchData)
{
if (searchData == null)
{
return BadRequest("no data");
}
var query = _db.TrackData.AsQueryable();
if (searchData.Artist)
{
query = query.Where(x => x.Artist.Contains(searchData.SearchTerm));
}
if (searchData.Album)
{
query = query.Where(x => x.AlbumTitle.Contains(searchData.SearchTerm));
}
if (searchData.Title)
{
query = query.Where(x => x.Title.Contains(searchData.SearchTerm));
}
return Ok(await query.ToListAsync());
}
}
}
感谢Tao Gómez Gil提供了解决方案,我不知道Predicate,但这成功解决了我的问题。我的控制器的修改后的代码如下,这应该对其他人有帮助。
using LinqKit;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Project.Context;
using Project.Models;
namespace Project.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class SearchController : ControllerBase
{
private readonly AppDbContext _db;
public SearchController(AppDbContext db)
{
this._db = db;
}
[Authorize]
[HttpPost]
public async Task<ActionResult<TrackData>> SearchAll([FromBody] SearchModel searchData)
{
if (searchData == null)
{
return BadRequest("no data");
}
// Instantiate Predicate, with a data type of TrackData (which is the data model returned)
var predicate = PredicateBuilder.New<TrackData>();
if (searchData.Artist)
{
// If searchData.Artist evaluates True, add the search term to the Or condition
predicate.Or(x => x.Artist.Contains(searchData.SearchTerm));
}
if (searchData.Album)
{
// If searchData.Album evaluates True, add the search term to the Or condition
predicate.Or(x => x.AlbumTitle.Contains(searchData.SearchTerm));
}
if (searchData.Title)
{
// If searchData.Title evaluates True, add the search term to the Or condition
predicate.Or(x => x.Title.Contains(searchData.SearchTerm));
}
// And now perform the query, with the Predicate within the Where clause
var query = _db.TrackData.AsNoTracking().Where(predicate);
// Output resultant query set
return Ok(await query.ToListAsync());
}
}
}