LINQ多对多关系:解决方案?

6

LINQ到目前为止一直非常优雅,但是对于执行基本的m2m查询,我没有立即看到任何解决方案。

更糟糕的是,虽然它适用于任何其他表关系,但LINQ在我的m2m表的类结构中没有给我提供关联。

所以我可以做一些事情,比如

artwork.artists.where(...)
//or
artist.Artworks.add(artwork)

但是我做不到

artwork.artowrks_subjects.tagSubjects.where(...)
//or
tagSubject.artworks_subjects.add(artwork)

alt text http://img299.imageshack.us/img299/257/20090902122107.png

有没有解决这个限制的常见模式?


由于某些原因,m2m 对我来说听起来很脏... 考虑拼写出它吧 ; ) - TJB
4个回答

5

我是如何在LINQ2SQL中实现M2M的:

  1. 将表格拖入构建器中,就像您在问题中展示的那样
  2. 删除“artworks_subject”和“artwork”之间的关系
  3. 从“artworks_subject”创建一个新的关系到“artwork”
  4. 单击新关系以获取其属性
  5. 将基数从OneToMany更改为OneToOne(因为ManyToOne不存在)
  6. 打开Child Property部分并将名称字段更改为单数形式(从Artworks到Artwork)

现在,“tagSubject”实体将有一个“artwork_subjects”的集合,而“artwork_subject”将具有类型为“artwork”的属性,称为“Artwork”。因此,您现在可以创建一个类似于以下的LINQ表达式:

var x = dbcontext.tagSubjects.Single(s=>s.name=="Landscape").
    Artwork_Subjects.
    Select(as=>as.Artwork.Name);

3

我自己找到了解决方案。为了让自动关联起作用,两个表都需要主键(糟糕)。请注意,artworks_subjects缺少PK符号。


2
这在很大程度上取决于您使用的框架。听起来您正在使用LINQ-to-SQL,它对表格到对象非常字面意义。对于Entity Framework,有内置支持多对多关系,特别是对于你列出的微不足道的情况(没有附加属性的链接表)。EF通常会发现这种模式,并从概念模型中隐藏链接表(我记不清了,但可能需要跨越两个FK列的跨度PK)。
当然,如果您想向链接表添加列,这将使事情变得复杂。因此,在某些方面上,我倾向于将其“保持原样”。
关于where等的问题 - 你是什么意思?您可以通过关联进行连接,并且应该能够使用Any等; 您有一个具体的例子吗?

基本上就是我展示的那样。目标是向艺术品对象添加标签。唯一合理的连接方式是多对多。到目前为止,我看到的使用LINQ-to-SQL的方法只能运行循环,创建艺术品主题对象,并手动绑定它们。我发现很奇怪的是,我甚至不能在艺术品和艺术品主题表之间进行一对多的连接(同样适用于标签主题和艺术品主题)。 - Justin Alexander

-1

是的。可以使用两个多对一关系,而不是多对多关系:

Subject -*----1- ArtworkSubjectParticipation -1----*- Artwork

2
这不就是OP在截图中已经得到的吗? - Marc Gravell
这是我所拥有的相反的情况,但最终结果意味着只能将一个标签与一件艺术品关联,这并不是目标。 - Justin Alexander
@Marc,原帖中的图片显示了关系型数据库结构。面向对象的结构不同,是多对多的。 - Dmytrii Nagirniak
@Justin,不行。如果有两个多对一的关联,就可以有隐式的多对多的关联。 - Dmytrii Nagirniak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接