【问题标题】:Exposing data from connected tables in Entity Framework Core MVC app在 Entity Framework Core MVC 应用程序中公开连接表中的数据
【发布时间】:2021-04-04 12:41:39
【问题描述】:

我的应用有 Product、ProductTags、Tags 表。我可以从 Products 访问 ProductTags,例如产品.产品标签。我可以通过循环 Product.ProductTags 来访问单个标签,如下所示:

List<Tag> tags = new List<Tag>();
foreach (var pt in product.ProductTags)
{
   tags.Add(pt.Tag);
}

但是,有没有一种简单的方法可以访问产品的所有标签列表,例如Product.Tags 而不是必须遍历 ProductTags 列表来公开每个单独的标签?然后类似地使写回标签时更容易。

我的模型如下,尽管删除了一些字段以便于阅读:

public class Product
{
    public int Id { get; set; } // ID (Primary key)
    public string Name { get; set; } // Name
    
    public virtual ICollection<ProductTag> ProductTags { get; set; } 
    public virtual ICollection<Tag> Tags { get; set; } 
    public Product()
    {
        ProductTags = new List<ProductTag>();
    }
 }

 public class ProductTag
 {
    public int ProductTagId { get; set; } 
    public int TagId { get; set; } 
    public int ProductId { get; set; } 

    public virtual Product Product { get; set; } 
    public virtual Tag Tag { get; set; }       
}

public class Tag
{
    public int TagId { get; set; } // TagID (Primary key)
    public string Name { get; set; } // Name
    
    public virtual ICollection<ProductTag> ProductTags { get; set; } 

    public Tag()
    {
        ProductTags = new List<ProductTag>();
    }
}

编辑: 在我的 ProductController 中,这是我检索数据的方式:

var product = await _context.Products
   .Include(pt => pt.ProductTags)
   .ThenInclude(t => t.Tag)
   .FirstOrDefaultAsync(m => m.Id == id);

这给了我一个 product.ProductTags 列表,但不是 product.Tags。

最后,我想编辑产品的标签列表,所以做类似这个例子的事情,我可以传入一个标签列表来添加或删除:

public virtual void AddTags(IEnumerable<Tag> tags, TagType tagType, Product product)
{
    if (tags == null) throw new ArgumentNullException("tags");
    if (tags.Count(t => t.TagType != tagType) > 0) throw new ArgumentException("Tags of multiple types supplied");

    var tagsToRemove = product.Tags.Where(t => !tags.Contains(t) && t.TagType == tagType).ToList();
    foreach (var t in tagsToRemove)
        this.Tags.Remove(t);

    foreach (var t in tags)
        if (!this.Tags.Contains(t))
            this.Tags.Add(t);
    }

【问题讨论】:

  • 使用急切或显式加载。 Loading Related Data
  • 谢谢,但是对于模型,我只能包含 Product.ProductTags,而不是 Product.Tags 这种方式,所以我认为我的模型需要更改?

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


【解决方案1】:

这可能会有所帮助:https://docs.microsoft.com/de-de/ef/core/querying/related-data/eager

您可以使用 Include 方法指定要包含在查询结果中的相关数据:

var products = context.Products
        .Include(m => m.ProductTags)
        .ToList();

您还可以包含多个导航属性:

var products = context.Products
            .Include(m => m.Tags)
            .Include(m => m.ProductTags)

或者甚至将ProductTags-Property 中的Tag 包含在ThenInclude() 中:

var products = context.Products
                .Include(m => m.ProductTags)
                .ThenInclude(m => m.Tag)

【讨论】:

    【解决方案2】:

    这是最简单地展示了如何正确设置模型的示例

    https://www.davidhayden.me/blog/ef-core-5-many-to-many-relationships

    【讨论】:

      猜你喜欢
      • 2021-11-06
      • 1970-01-01
      • 2021-10-02
      • 1970-01-01
      • 1970-01-01
      • 2018-02-27
      • 2018-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多