LINQ to SQL和自关联表

3
我们在dbml文件中有以下测试模型:

模型 http://www.freeimagehosting.net/uploads/a86582498a.gif

对于测试用例,表中有4条记录,1个父级和3个子级。我们正在寻找特定记录的兄弟姐妹,包括特定记录本身。
using (var db = new TestDataContext())
{
    var query = 
        from f in db.Foos
        where f.Name == "Two"
        select f.Foo1.Foos;              // get the record's parent's children

    var foos = query.SelectMany(f => f); // project the EntitySet

    Assert.AreEqual(3, foos.Count());    // passes
}

这个SQL语句可以正确返回相应的数据项:
SELECT     [t2].[FooId], 
           [t2].[ParentFooId], 
           [t2].[Name]
FROM       [dbo].[Foos] AS [t0]
INNER JOIN [dbo].[Foos] AS [t1] ON [t1].[FooId] = [t0].[ParentFooId]
CROSS JOIN [dbo].[Foos] AS [t2]
WHERE      ([t0].[Name] = @p0) 
AND        ([t2].[ParentFooId] = [t1].[FooId])

我们想了解CROSS JOIN,这显然是SelectMany的结果吗?
是否还有其他方法可以避免使用CROSS JOIN?

3个回答

1

在 Linq 查询中,您可以堆叠 from 语句,这可能会对您有所帮助。

var query = from f in db.Foos
            from f2 in f.Foos
            where f.Name == "Two"
            select f2;

这将产生。

SELECT [t1].[FooId],
       [t1].[Name],
       [t1].[ParentFooId]
FROM [dbo].[Foos] AS [t0], [dbo].[Foos] AS [t1]
WHERE ([t0].[Name] = @p0) AND ([t1].[ParentFooId] = [t0].[FooId])

那么既然没有指定,这将让 SQL Server 决定连接的类型? - blu
是的。默认情况下,这是一个内连接。 - Jacob Proffitt
据我理解,逗号将决定连接方式由SQL Server来确定;它可以是内连接也可以是交叉连接。如果有相关实现的参考,那就太好了。 - blu

0

你也可以选择这样做:

var query = from f in db.Foos
            where (from fo in db.Foos
                   where fo.Name == "Two"
                   select fo.ParentId).Contains(f.ParentId)
            select f;

这应该会产生类似以下的结果:

SELECT     [t1].[FooId], 
           [t1].[ParentFooId], 
           [t1].[Name]
FROM       [dbo].[Foos] AS [t1]
WHERE      [t1].[ParentFooId] IN (SELECT [t0].[ParentFooId]
                                  FROM [dbo].[Foos] AS [t0]
                                  WHERE[t0].[Name] = @p0)

可能会有所不同(取决于您的模型),可能会有一个Exists()...我手头没有分析器窗口。


0

试试这个:

var siblings = DataContext.Foos.Where(a => a.FooID == 3)
    .Select(b => Foos.Where(b => Foos.ParentFooID == a.ParentFooID));

Assert.AreEqual(3, siblings.Count());

你缺少一个闭括号! - user57508

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