【问题标题】:How to make a join table using EF core code first如何首先使用 EF 核心代码制作连接表
【发布时间】:2017-05-22 22:55:09
【问题描述】:

我有这三个模型:

public class Card
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Class { get; set; }
    public string Image { get; set; }
}

public class Deck
{
    public int ID {get; set;}
    public string Name {get; set;}
    public string Class {get; set;}
    public virtual ICollection<DeckCard> DeckCards {get; set;}
}

public class DeckCard
{
    public int ID {get; set;}
    public int DeckID {get; set;}
    public int CardID {get; set;}
}

我想将 DeckCard 模型本质上用作连接表。我需要能够在我的 DecksController/Index 视图中填充它。谁能给我指导或指出正确的方向?

请注意,卡片表是一个静态表(我不知道这是否是正确的术语,但它会被游戏当前拥有的任何卡片填充并保持不变(这是一个套牌构建网站)。

【问题讨论】:

  • 你想要什么作为连接结果?你尝试了什么?
  • 我希望连接结果是 DeckCard 类型的实体。对不起,如果这听起来很愚蠢,但我对此非常陌生。
  • 您想要特定的套牌? (DeckId.. ???)。
  • 是的。对于数据库中的每个牌组。用户将创建自己的套牌。
  • 它本质上是牌组中的一张牌列表(针对每个现有牌组)。另一种方法是创建卡片类型的 nav 属性,但在制作过程中,卡片类型在每次用于组成牌组时都会有太多信息需要复制。我宁愿只有一张身份证号码表。

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


【解决方案1】:

首先。您无需为一对多关系创建模型(DeckCard),以便 EF 自动在您的数据库中创建此表。

第二个。在您的 DbContext 类中添加或覆盖 OnModelCreating 方法 例如:

MyApplicationDbContext.cs

 public class MyApplicationDbContext : DbContext
 {
     public DbSet<Card> Cards { get; set; }
      
     public DbSet<Deck> Decks { get; set; }

     //This is the Model Builder
     protected override void OnModelCreating(DbModelBuilder modelBuilder)
     { 
           modelBuilder.Entity<Card>()
                .HasRequired<Card>(_ => _.Card)
                .WithMany(_ => _.Deck);
                
     }

 }

DecksController.cs

 public ActionResult Index()
 { 
      var model = context.Card.AsNoTracking().Include(_ => _.Decks).ToList(); 
        
      return View(model);
 }

对于带有急切加载的连接查询,请使用Include();

另外,请参阅下面的链接:

Getting more performance out of Entity Framework 6

Entity Framework Loading Related Entities

Configure One-to-Many Relationship

Relationships In EF Core

【讨论】:

  • 我正在使用 EF 核心,我将编辑标题以指定它,但 '.HasRequired' 不是我正在使用的任何指令的方法。有没有等价的核心?这段代码是否建立了一对多的关系,当您定义导航属性时,EF 是否假定(公共虚拟 ICollection Cards {get; set;} 将自动映射具有属性 ID 的 Card 类型的实体到具有导航属性定义的实体...对吗?
  • 在一对多的关系中,1 是 Card 而 many 是 Deck 对吧?根据这段代码?
  • @j3ssi3ftw 是的,认为link 非常适合您的问题。
  • @j3ssi3ftw in this link that is Microsoft doc Can Help you.
  • 关系应该是多对多的吧?毫无疑问,每张牌将用于不止一副牌。
【解决方案2】:

使用您当前的实体结构,您可以编写所有三个数据集之间的连接,然后对 DeckId 进行分组并得出结果。

我将为我的视图的这个分组数据表示创建 2 个视图模型类。

public class DeckVm
{
    public int Id { set; get; }
    public string Name { set; get; }
    public IEnumerable<CardVm> Cards { set; get; }
}
public class CardVm
{
    public int Id { set; get; }
    public string Name { set; get; }
}

现在加入

var decksWithCards = (from dc in db.DeckCards
                join d in db.Decks on dc.DeckID equals d.ID
                join c in db.Cards on dc.CardID equals c.ID
                select new { DeckId = d.ID, DeckName = d.Name,
                             CardId = c.ID, CardName = c.Name })
    .GroupBy(x => x.DeckId, d => d,
        (ky, v) =>
            new DeckVm
            {
                Id = ky,
                Name = v.FirstOrDefault().DeckName,
                Cards = v.Select(h => new CardVm { Id = h.CardId, Name=h.CardName})
            })
    .ToList();

decksWithCards 将是一个List&lt;DeckVm&gt;,您可以将其传递给您的视图。您必须将您的视图强类型化为List&lt;DeckVm&gt;

【讨论】:

    猜你喜欢
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    • 2016-06-06
    • 2012-02-01
    相关资源
    最近更新 更多