【问题标题】:How to use Linq to join entity tables with a cross-reference table如何使用 Linq 将实体表与交叉引用表连接起来
【发布时间】:2015-02-22 00:40:15
【问题描述】:

让我先说我对 Linq 比较陌生,但我似乎很快就掌握了其中的大部分内容。但是这个问题让我很困惑。我找了又找,没有用。

我使用代码优先并创建了 2 个模型,“项目”和“关键字”。他们有一个多对多的关系。我的实体模型如下所示:

public class MyContext : DbContext
{
    public MyContext() : base("name=DefaultDatabase") { }

    protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Mapping Xref table to the correct DB table
        modelBuilder.Entity<Item>()
          .HasMany(i => i.Keywords)
          .WithMany(k => k.Items)
          .Map(ik =>
          {
              ik.ToTable("ItemKeywords", "MySchema");
              ik.MapLeftKey("ItemId");
              ik.MapRightKey("KeywordId");
          });

    }

    public virtual DbSet<Item> Items { get; set; }
    public virtual DbSet<Keyword> Keywords { get; set; }

}

public class Item
{

    public Item()
    {
        Keywords = new List<Keyword>();
    }

    public int ItemId { get; set; }
    public string Text { get; set; }
    public virtual List<Keyword> Keywords { get; set; }

}

public class Keyword
{

    public Keyword()
    {
        Items = new HashSet<Item>();
    }

    public int KeywordId { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Item> Items { get; set; }

}

据我所知,这很简单。当我的迁移生成数据库时,我得到 3 个表,“Items”、“Keywords”和“ItemKeywords”的交叉引用表(我在“OnModelCreating”方法中映射)。

我遇到的问题是创建 Linq 查询(查询语法或方法语法,我不在乎)来重现这个:

SELECT DISTINCT
    i.*
FROM
    Items i
    INNER JOIN ItemKeywords ik
        ON i.ItemId = ik.ItemId
    INNER JOIN Keywords k
        ON ik.KeywordId = k.KeywordId
WHERE
    k.KeywordId IN (1, 3, 5, 7, 9)

所以,基本上,我想要一个不同的项目列表,其中一个指定的关键字分配给它们。

我想我可以通过创建一个 ItemKeyword 模型让它工作,但这似乎会破坏代码优先的观点。我会在其中添加一个额外的模型,只是为了能够对其进行查询。

有没有办法在不添加第三个外部参照模型的情况下让它工作?

谢谢!

【问题讨论】:

    标签: .net linq entity-framework entity entity-framework-6


    【解决方案1】:

    我认为您要查找的是这样的查询:

     var keywordIds = new List<int> {1, 3, 5, 7, 9};
     var items =   (from s in db.Items
                    from c in s.Keywords
                    where keywordIds.Contains(c.KeywordId)
                    select s).Distinct();
    

    如果您想将所有选定的项目带入内存,请在此查询结束时调用ToList 方法。

    【讨论】:

    • 效果很好。一旦我看到它是如何完成的,它就变得如此简单。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    • 2023-03-18
    相关资源
    最近更新 更多