我来自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();
这将获取所有产品及其各自的标签,包括没有标签的产品。希望它能以正确的理由运作......
答案 0 :(得分:0)
使用像EF这样的对象关系映射器的目的是为你映射关系。如果你手动连接数据库中有外键的对象,那你就错了。< / p>
请参阅我的问题Why use LINQ Join on a simple one-many relationship?
正确答案只是context.Products.Include("Tags")
,它会自动为您自动加入产品和标签。这实际上是使用ORM的最大(唯一?)好处。