Entity Framework 7 - 多个Where条件,如果布尔值等于true[重复]

问题描述 投票:0回答:1

我仍在完全学习和理解实体框架,但正在致力于一个个人项目,旨在增加学习。

目前我有一个搜索功能,可以搜索艺术家、专辑或标题(或任意三者的组合)。

为了简化我在此处添加的代码量,我有一个带有复选框的 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());
        }
    }
}
entity-framework .net-core entity-framework-core
1个回答
0
投票

感谢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());
        }
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.