实体框架:在多对多关系中获取具有链接模型的模型

时间:2012-04-04 03:59:53

标签: linq entity-framework many-to-many

我来自TSQL + C#land并且一直在努力适应linq和EF。多对多的关系一直困扰着我。我有一些具有多对多关系的模型,我想从数据库中查询。如:

     class Product{
       public int ID {get;set;}
       public string ProductName {get;set;}
       public virtual ICollection<Tag> Tags {get;set;}
     }

   class Tag {
       public int ID {get;set;}
       public string TagName {get;set;}
       public virtual ICollection<Product> Products {get;set;}

    }

我能够从DbContext中获取产品本身,然后再获取它的相关标签,如下所示:

// product exists in memory as a Product with an empty product.Tags

var query = from p in db.Product
            from t in db.Tags
            where p.ID == product.ID
            select p.Tags;

然后我可以分配产品。标记带有标签。显然,如果我必须查询每个产品,这在处理多个产品时效率非常低。

使用linq和EF,我希望能够在数据库的往返中获得一个包含所有相关标签的产品。此外,我希望能够获取所有产品及其相关标签(或过滤的产品列表)。 linq怎么样?

编辑:

好的,经过一些更多的摆弄,我得到了这个:

var query = db.Product.Include("Tags")
            .Where(p => p.Tags.Any(t => t.Products.Select(m => m.ID).Contains(p.ID)));

这几乎是我的需要。结果是所有带标签的产品。缺少的是没有标签的产品。我认为这相当于SQL内连接。我想将外部加入标签添加到产品中,并返回带有标签的所有产品可选。如何使用相关标签获取所有产品而不排除没有标签的产品?

编辑:

这比我想象的容易。

var query2 = db.Product.Include("Tags").DefaultIfEmpty();

这将获取所有产品及其各自的标签,包括没有标签的产品。希望它能以正确的理由运作......

1 个答案:

答案 0 :(得分:0)

使用像EF这样的对象关系映射器的目的是为你映射关系。如果你手动连接数据库中有外键的对象,那你就错了。< / p>

请参阅我的问题Why use LINQ Join on a simple one-many relationship?

正确答案只是context.Products.Include("Tags"),它会自动为您自动加入产品和标签。这实际上是使用ORM的最大(唯一?)好处。