【问题标题】:LINQ to SQL and Self Related TableLINQ to SQL 和自相关表
【发布时间】:2010-02-04 23:47:33
【问题描述】:

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

Model 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,我们还有其他方法可以解决这个问题吗?

【问题讨论】:

    标签: c# sql linq-to-sql orm


    【解决方案1】:

    您可以从 Linq 查询中的语句堆叠起来,这可能会对您有所帮助。

    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,因为没有指定?
    • 是的。默认情况下,这是一个内部连接。
    • 据我了解,',' 将由 SQL Server 决定加入;它可能是内部连接,也可能是交叉连接。如果不是对该实现的引用,那就太好了。
    【解决方案2】:

    你也可以这样做:

    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(),具体取决于您的型号)...我手边没有分析器窗口。

    【讨论】:

      【解决方案3】:

      试试这个:

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

      【讨论】:

      • 你缺少右括号!
      猜你喜欢
      • 1970-01-01
      • 2011-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多