我已经使用LINQ to SQL和Entity Framework几年了,我总是映射我的数据库关系以生成相关的导航属性。我总是使用导航属性。
我错过了什么吗?
如果我有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
语法有什么好处?
答案 0 :(得分:9)
@George是正确的,但是您的两个示例在功能上有所不同,但与join
与非join
无关。但你可以这么容易写:
var redProducts = context.Category
.Where(c => c.Name == "red")
.SelectMany(c => c.Products);
...功能相同(但高级从可读性和可维护性POV)到您的join
示例。
答案 1 :(得分:4)
将旧代码移植到linq2sql可能会导致这种情况。
但是,这两个代码片段在功能上并不相同。
Single
将抛出异常,而join
会在缺少记录时产生空集合。
因此,不使用连接的相同代码将是:
from c in context.Categories where c.Name == "red" from p in c.Products select p;
或
context.Categories.Where(c=>c.Name == "red").SelectMany(c=>c.Products);
答案 2 :(得分:3)
对于来自Relational心态而不是面向对象的人来说,联接可能更常见。如果从对象的角度考虑你的问题空间,那么处理你可以点击导航的关系就更自然了:Employee.Customers.Orders.OrderItems.OrderItem
而不是处理一堆连接。最初的ADO.vNext白皮书很好地讨论了使用模型和关联而不是连接来处理概念模型的优势。不幸的是,我现在找不到那份文件。
对我来说,当实体之间没有自然关联时,最好使用连接。例如,如果您尝试在非自然键上加入项目(即加入Customer.State
和Shipping.State
),则应使用连接语法(或SelectMany
)而不是在您的关联之间创建关联在这种情况下的实体。
需要注意的一点是,连接语法和使用关联可能会导致提供程序生成的连接类型存在差异。通常,Join转换为内部联接,并排除联接两侧不匹配的项目。要执行(左)外部联接,请使用DefaultIfEmpty
扩展名。
另一方面,在1-0 .. *关系中浏览关联通常会转换为右外连接,因为子集合可能合法地为空,即使子节点不存在,您也希望包含父节点。如果没有子记录,您可以使用!Any()
陷阱。