LinqToSql中有多个左外连接?

时间:2009-10-16 19:05:13

标签: c# .net linq-to-sql c#-3.0

是否可以使用linqtosql完成类似的操作?

select * from table t1
left outer join table2 t2 on t2.foreignKeyID=t1.id
left outer join table3 t3 on t3.foreignKeyID=t1.id

我可以使用DataLoad选项或连接语法使其工作。但问题是每当我添加第二个左连接时,linqtosql查询使用MULTIPLE sql语句,而不是在底层sql中进行第二次左连接。

因此,如上所述的查询将导致数十个sql调用,而不是一个带有2个左连接的sql调用。

我的其他选择是什么?我可以在数据库中使用一个视图,但现在我负责从拼合列表创建层次结构,这是首先使用ORM的原因之一。

注意T2和T3与T1的关系为1:M。是否有可能让linq有效地查询这些并返回层次结构?

4 个答案:

答案 0 :(得分:1)

Here is a similar question。要知道联接的组成方式。

例如,在AdventureWorks上进行以下Linq to Sql查询:

AdventureWorksDataContext db = new AdventureWorksDataContext();

var productStuff = from p in db.Products
                   join pl in db.ProductListPriceHistories on p.ProductID equals pl.ProductID into plv
                   from x in plv.DefaultIfEmpty()
                   join pi in db.ProductInventories on p.ProductID equals pi.ProductID into pii
                   from y in pii.DefaultIfEmpty()
                   where p.ProductID == 764
                   select new { p.ProductID, x.StartDate, x.EndDate, x.ListPrice, y.LocationID, y.Quantity };

与此SQL查询产生相同的SQL(通过Profiler验证):

SELECT Production.Product.ProductID, 
       Production.ProductListPriceHistory.StartDate,
       Production.ProductListPriceHistory.EndDate,
       Production.ProductListPriceHistory.ListPrice,
       Production.ProductInventory.LocationID,
       Production.ProductInventory.Quantity
FROM Production.Product
LEFT OUTER JOIN Production.ProductListPriceHistory ON Production.Product.ProductID = Production.ProductListPriceHistory.ProductID 
LEFT OUTER JOIN Production.ProductInventory ON Production.Product.ProductID = Production.ProductInventory.ProductID 
WHERE Production.Product.ProductID = 764

父表的主键上有多个LEFT JOIN,产生一个生成的SQL查询。

答案 1 :(得分:1)

我不认为这可能是您问题的正确解决方案,因为您的父实体表有多个多对一关系:

select * from table t1 
left outer join table2 t2 on t2.foreignKeyID = t1.id 
left outer join table3 t3 on t3.foreignKeyID = t1.id 

这就像一个有多个孩子和多辆车的人:

说t1是那个人

id             str
1              Me

说t2是孩子

PK  foreignKeyID   str
A   1              Boy
B   1              Girl

说t3是车辆

PK  foreignKeyID   str
A   1              Ferrari
B   1              Porsche

您的结果集是:

Me Boy Ferrari
Me Girl Ferrari
Me Boy Porsche
Me Girl Porcshe

我没有看到这是一个有用的查询(即使在SQL中)。

答案 2 :(得分:0)

我认为只要将DefaultIfEmpty()调用放在正确的位置,LINQ to SQL就能够转换左外连接:

var q = from t1 in table
        join t2 in table2 on t1.id equals t2.foreignKeyID into j2
        from t2 in j2.DefaultIfEmpty()
        join t3 in table3 on t1.id equals t3.foreignKeyID into j3
        from t3 in j3.DefaultIfEmpty()
        select new { t1, t2, t3 };

答案 3 :(得分:0)

如果您正确设置了FK,则不需要那种可怕的连接语法。

您可能会写:

var q = from t1 in dc.table1s
        from t2 in t1.table2s.DefaultIfEmpty()
        from t3 in t1.table3s.DefaultIfEmpty()
        select new { t1, t2, t3 };