【问题标题】:How make query for getting some objects from many-to-many model, using EF core? [duplicate]如何使用 EF 核心查询从多对多模型中获取一些对象? [复制]
【发布时间】:2020-03-08 00:32:38
【问题描述】:

我尝试这样做:

var articles = db.Articles.Include(at => at.ArticleTags)
                          .ThenInclude(t => t.Tag)
                          .ToList();

var articlesTag = articles.Where(a => a.ArticleTags.Tag.TagValue == "news").ToList();

但它不起作用。 Visual Studio 看不到此表达式“a.ArticleTags.Tag.TagValue”。我怎样才能做到正确?

这里是使用的类的实现:

public class Tag
{
    public int Id { get; set; }
    public string TagValue { get; set; }
    public List<ArticleTag> ArticleTags { get; set; }
    public List<UserTag> UserTags { get; set; }

    public Tag()
    {
        ArticleTags = new List<ArticleTag>();
        UserTags = new List<UserTag>();
    }
}

public class Article
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Summary { get; set; }
    public List<ArticleTag> ArticleTags { get; set; }

    public Article()
    {
        ArticleTags = new List<ArticleTag>();
    }
}

public class ArticleTag
{
    public int ArticleId { get; set; }
    public Article Article { get; set; }

    public int TagId { get; set; }
    public Tag Tag { get; set; }
}

【问题讨论】:

    标签: c# .net-core entity-framework-core


    【解决方案1】:

    基本上IncludeThenInclude 的唯一作用是告诉 EF 在从数据库中请求数据时加载这些嵌套对象。它不允许您忽略 ArticleTag 是一个对象列表这一事实,您需要使用此类对象的可用方法之一。所以在这种情况下,您想将Find 应用于ArticleTag 列表。

    编辑:

    请参阅下面的完整示例。请注意,通过向 EF 指示模型之间的关系,我什至不需要费心包含数据(后面的示例)。

    模型创建:

            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
    
                modelBuilder.Entity<Article>().HasData(
                    new Article { Id = 1, Summary = "Article summary 1", Title = "Article title 1" },
                    new Article { Id = 2, Summary = "Article summary 2", Title = "Article title 2" },
                    new Article { Id = 3, Summary = "Article summary 3", Title = "Article title 3" },
                    new Article { Id = 4, Summary = "Article summary 4", Title = "Article title 4" },
                    new Article { Id = 5, Summary = "Article summary 5", Title = "Article title 5" },
                    new Article { Id = 6, Summary = "Article summary 6", Title = "Article title 6" });
    
                modelBuilder.Entity<Article>().HasKey(a => a.Id);
                modelBuilder.Entity<Article>().HasMany(a => a.ArticleTags).WithOne(at => at.Article);
    
                modelBuilder.Entity<Tag>().HasData(
                    new Tag { Id = 1, TagValue = "Tag 1" },
                    new Tag { Id = 2, TagValue = "Tag 2" });
    
                modelBuilder.Entity<Tag>().HasKey(t => t.Id);
                modelBuilder.Entity<Tag>().HasMany(t => t.ArticleTags).WithOne(at => at.Tag);
    
                modelBuilder.Entity<ArticleTag>().HasData(
                    new ArticleTag { ArticleId = 1, TagId = 1 },
                    new ArticleTag { ArticleId = 2, TagId = 1 },
                    new ArticleTag { ArticleId = 1, TagId = 2 },
                    new ArticleTag { ArticleId = 2, TagId = 2 },
                    new ArticleTag { ArticleId = 3, TagId = 1 },
                    new ArticleTag { ArticleId = 4, TagId = 2 });
    
                modelBuilder.Entity<ArticleTag>().HasKey(at => new { at.ArticleId, at.TagId });
                modelBuilder.Entity<ArticleTag>().HasOne(at => at.Article).WithMany(a => a.ArticleTags);
                modelBuilder.Entity<ArticleTag>().HasOne(at => at.Tag).WithMany(t => t.ArticleTags);
    
                // Tag 1: Article 1,2,3
                // Tag 2: Article 1,2,4
                base.OnModelCreating(modelBuilder);
            }
    

    控制器:

            public async Task<IActionResult> Index()
            {
                db.Database.EnsureCreated();
                var articles = db.Articles.Include(at => at.ArticleTags)
                              .ThenInclude(t => t.Tag);
    
                var articlesTag1 = articles.Where(a => a.ArticleTags.Any(at => at.Tag.TagValue == "Tag 1")).ToList();
    
                var articlesTag2 = articles.Where(a => a.ArticleTags.Any(at => at.Tag.TagValue == "Tag 2")).ToList();
    
                var articles1 = await db.ArticleTags.Include(at => at.Article)
                              .Include(at => at.Tag)
                              .Where(at => at.Tag.TagValue == "Tag 1").ToListAsync();
    
                var articles2 = await db.ArticleTags
                              .Where(at => at.Tag.TagValue == "Tag 2").ToListAsync();
                return View();
            }
    

    如您所见,您可以从中间表开始,使其更容易,不需要包含链 thst 将钻取数据。

    【讨论】:

    • 谢谢。但是我仍然不明白如何获取所有带有相应标签的文章。你可以举个例子。
    • 查看更新的答案,我为你创建了一个完整的例子,只检查了 InMemory db。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多