通过LINQ中的联结表将表连接在一起

时间:2013-02-13 11:22:08

标签: c# linq

当我在多对多关系中使用三个表时,我想知道如何完成与导航属性相同的操作。

首先,我有一些测试代码让我们开始:

var table1 = new[]
{
    new { Title = "Title1", Id = 1 },
    new { Title = "Title2", Id = 2 },
    new { Title = "Title3", Id = 3 }
};
var table2 = new[]
{
    new { GameId = 1, GenreId = 1 },
    new { GameId = 1, GenreId = 2 },
    new { GameId = 1, GenreId = 3 },
    new { GameId = 2, GenreId = 1 },
    new { GameId = 2, GenreId = 2 },
    new { GameId = 3, GenreId = 1 }
};
var table3 = new[]
{
    new { Name = "Genre1", Id = 1 },
    new { Name = "Genre2", Id = 2 },
    new { Name = "Genre3", Id = 3 }
};

“table1”包含一些游戏的标题,例如“table3”包含一些类型,“table2”通过其id将“table1”与“table3”连接起来。

现在我的问题是你如何最优雅地选择一个游戏列表(table1),每个游戏都有一个类型列表(table3)到一个匿名类型列表中?

到目前为止,我的解决方案是:

var query =
    from t1 in table1
    select new
    {
        Game = t1,
        Genres =
        (
            from t2 in table2
            join t3 in table3 on t2.GenreId equals t3.Id
            where t2.GameId == t1.Id
            select t3
        ).ToList()
    };
var result = query.ToList();

理想情况下,我想避免使用子查询,但问题是在这种情况下是否可以避免...

我在想这样的事情:

var query =
    from t1 in table1
    join t2 in table2 on t1.Id equals t2.GameId
    join t3 in table3 on t2.GenreId equals t3.Id
    select new { Game = t1, Genres = t3 };
var result = query.ToList();

当然会返回六项,这不是我想要的结果。

总而言之:在LINQ中是否可以选择列表游戏(table1),每个列表都包含其类型列表(table3)而不使用子查询?

2 个答案:

答案 0 :(得分:4)

也许您只想将第二个查询与group by

合并
var query =
    from t1 in table1
    join t2 in table2 on t1.Id equals t2.GameId
    join t3 in table3 on t2.GenreId equals t3.Id
    group t3 by t1 into g
    select new { Game = g.Key.Title, Genres = g.Select (x => x.Name) };

enter image description here

注意:应该很明显,但我只是用select new { Game = g.Key.Title, Genres = g.Select (x => x.Name) }来说明。要选择实际类型,请使用select new { Game = g.Key, Genres = g }

答案 1 :(得分:2)

使用group

var query =
    from t1 in table1
    join t2 in table2 on t1.Id equals t2.GameId
    join t3 in table3 on t2.GenreId equals t3.Id
    group t3 by t1 into g
    select new { Game = g.Key, Genres = g.ToList() };

var result = query.ToList();

现在result是一个匿名类型列表,其中Game来自table1,而Genres是来自table3的内容列表。