LINQ to SQL и собственная таблица - PullRequest
3 голосов
/ 05 февраля 2010

У нас есть следующая тестовая модель в файле 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 голос
/ 05 февраля 2010

Вы можете составлять из операторов в запросе 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])
0 голосов
/ 05 февраля 2010

Попробуйте это:

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

Assert.AreEqual(3, siblings.Count());
0 голосов
/ 05 февраля 2010

Вы могли бы альтернативно сделать:

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() в зависимости от вашей модели) ... У меня нет удобного окна профилировщика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...