为什么在简单的一对多关系上使用 LINQ Join?
我使用 LINQ to SQL 和实体框架已有几年了,并且始终映射数据库关系以生成相关的导航属性。我总是使用导航属性。
我错过了什么吗?
如果我有一个 Category->Products
一对多类型关系,我会
var redProducts = context.Category.Single(c => c.Name = "red").Products;
经常看到人们在这个网站、在线项目和各种其他网站上进行手动连接。
var employer = from category in context.Categories
join product in context.Products
on category.CategoryId equals product.CategoryId
where category.Name == "red"
select product;
那么 - 为什么?使用此 Join
语法有什么好处?
I've been using LINQ to SQL and Entity Framework for a few years and I've always mapped my database relationships to generate the relevant navigation properties. And I always use the navigation properties.
Am I missing something?
If I have a Category->Products
one-many type relationship, I would use
var redProducts = context.Category.Single(c => c.Name = "red").Products;
I regularly see people doing manual joins, all over this site, in projects online, and various other websites.
var employer = from category in context.Categories
join product in context.Products
on category.CategoryId equals product.CategoryId
where category.Name == "red"
select product;
So - why? What are the benefits of using this Join
syntax?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这可能是由于将旧代码移植到 linq2sql 造成的。
但是,这两个代码片段在功能上并不相同。
Single
将抛出异常,而join
在缺少记录的情况下会产生一个空集合。因此,不使用连接的相同代码将是:
或
It might result from porting the old code to linq2sql.
However, the two code snippets are not functionally equal.
Single
will throw exception, whilejoin
yields an empty collection in case of missing record.So, an equal code without using joins would be:
or
对于来自关系思维而不是面向对象思维的人来说,连接可能更常见。如果您从面向对象的角度考虑问题空间,那么处理可以在导航中点的关系比处理 Employee.Customers.Orders.OrderItems.OrderItem 更自然。一堆连接。最初的 ADO.vNext 白皮书很好地讨论了使用模型和关联而不是连接来处理概念模型的优点。不幸的是,我目前找不到该文档。
对我来说,当实体之间没有自然关联时,最好使用联接。例如,如果您尝试在非自然键上连接项目(即在
Customer.State
和Shipping.State
上连接),您应该使用连接语法(或SelectMany
),而不是在这种情况下在实体之间创建关联。需要注意的一件事是,连接语法和使用关联可能会导致提供程序生成的连接类型存在差异。通常,连接会转换为内部连接,并排除连接两侧不匹配的项目。要执行(左)外部联接,请使用
DefaultIfEmpty
扩展。另一方面,在 1-0..* 关系中导航关联通常会转换为右外连接,因为子集合可以合法地为空,并且即使子集合不存在,您也希望包含父集合。您可以使用
!Any()
来捕获没有子记录的情况。Joins are probably more common for people coming from the Relational mindset rather than the object oriented one. If you think about your problem space from a object orientented perspective, it is much more natural to work with relationships where you can dot through the navigation:
Employee.Customers.Orders.OrderItems.OrderItem
than to deal with a bunch of joins. The original ADO.vNext whitepaper did a good job of discussing the advantages of using the model and associations rather than joins for dealing with your conceptual models. Unfortunately, I can't find that document at this point.For me, joins are best used when you don't have natural associations between entities. For example, if you are trying to join items on unnatural keys (i.e. joining on the
Customer.State
andShipping.State
) you should use the join syntax (orSelectMany
) rather than creating associations between your entities in this case.One thing to be aware of is that the join syntax and using associations can cause differences in the kind of joins that are generated by the provider. Typically a Join translates into an Inner join and excludes items where there is no match on both sides of the join. To perform an (left) outer join, you use the
DefaultIfEmpty
extension.Navigating through associations in a 1-0..* relationship on the other hand typically translate into Right Outer joins because the child collection could legitimately be empty and you would want to include the parent even if the child didn't exist. You would use
!Any()
to trap for cases were there aren't child records.这通常是一个错误。
@George 是正确的,您的两个示例在功能上有所不同,与
join
和join
无关但是,非加入
。但您也可以轻松地编写:...这在功能上与您的
join
示例相同(但从可读性和可维护性 POV 来看优于)。It's usually a mistake.
@George is correct that your two examples are functionally different in a way which has nothing to do with
join
vs non-join
, however. But you could just as easily write:...which is functionally identical (but superior from a readability and maintainability POV) to your
join
example.