过滤EF Core 2.0中的相关表

时间:2017-10-05 22:14:40

标签: asp.net asp.net-mvc entity-framework asp.net-core ef-core-2.0

我正在研究.Net Core 2.0中的第一个项目。这是一个简单的博客系统。我想根据帖子标题和标签添加搜索功能。 我的实体:

public class Post
{

    public int ID { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string Body { get; set; }
    public int CategoryID { get; set; }
    public DateTime ReleaseDate { get; set; }
    public string ImageName { get; set; }

    public Category Category { get; set; }
    public ICollection<PostTag> PostTags { get; } = new List<PostTag>();
}

 public class PostTag
{

    public int PostID { get; set; }
    public int TagID { get; set; }

    public Post Post { get; set; }
    public Tag Tag { get; set; }

}

public class Tag
{
    public int TagID { get; set; }
    public string Name { get; set; }
    public int Counter { get; set; }
    public ICollection<PostTag> PostTags { get; } = new List<PostTag>();

    public Tag()
    {
        Counter = 1;
    }

到目前为止,我已经想出了类似的东西。我加入了Tag表,以便能够在IndexView中查看每个帖子的所有标签。

public async Task<IActionResult> Index(int? page, string searchString)
    {

        IQueryable<Post> posts = _context.Posts
            .OrderByDescending(post => post.ReleaseDate)
            .Include(post => post.Category)
            .Include(post => post.PostTags)
                .ThenInclude(pt => pt.Tag);

        //SEARCH
        if (!String.IsNullOrEmpty(searchString))
        {

            posts = posts.Where(post => post.PostTags.Any(pt => pt.Tag.Name.Contains(searchString)) || post.Title.Contains(searchString));

            //POPULARITY INCREESE
            var tag = _context.Tags.SingleOrDefault(t => t.Name == searchString);
            if (tag != null)
            {
                tag.Counter += 1;
                _context.Update(tag);
                _context.SaveChanges();
            }
        }   

        int pageSize = 4;
        return View("Index", await PaginatedList<Post>.CreateAsync(posts.AsNoTracking(), page ?? 1, pageSize));

    }

它很蠢,但我想知道是否有更简单或更好的方法。 当我不包括相关表格时,功能是否会起作用?

1 个答案:

答案 0 :(得分:0)

首先回答您的上一个问题:只要您没有向数据库发送任何请求,就不需要Include()进行过滤。 如果要填充实体列表,并且要访问导航属性,例如迭代列表时,需要使用Include()。

如果要避免使用Include(),则应选择所需的值。这将避免使用NavigationProperties或类似的东西出现意外行为。我会做这样的事情:

IQueryable<Post> posts = _context.Posts.OrderByDescending(post => post.ReleaseDate);

    //SEARCH
    if (!String.IsNullOrEmpty(searchString))
    {

        posts = posts.Where(post => post.PostTags.Any(pt => pt.Tag.Name.Contains(searchString)) || post.Title.Contains(searchString));

        //POPULARITY INCREESE
        var tag = _context.Tags.SingleOrDefault(t => t.Name == searchString);
        if (tag != null)
        {
            tag.Counter += 1;
            _context.Update(tag);
            _context.SaveChanges();
        }
    }
int pageSize = 4;
return View("Index", await PaginatedList<Post>.CreateAsync(posts.AsNoTracking().Select(e=> new YourDisplayObject { DiplayValue = e.DbValue, DisplayNavProp = e.NavProp }, page ?? 1, pageSize));