C# 如何使用实体框架加载多对多对象图?

C# 如何使用实体框架加载多对多对象图?,c#,sql,linq,entity-framework,many-to-many,C#,Sql,Linq,Entity Framework,Many To Many,我有一个多对多关系(例如“Left”、“Right”和“joinerd”)和另一个实体“satelite”,它键入“Left”。碰巧Satelite的FK上也有一个唯一的索引。我的目标是为where子句使用卫星上的属性加载一个合并实体及其左右实体 我已经尝试了很多方法,但是我对Linq的词汇量很弱,我甚至不知道我要找的术语 var joinder = dbContext.Joinders .Include(j => j.Left)

我有一个多对多关系(例如“Left”、“Right”和“joinerd”)和另一个实体“satelite”,它键入“Left”。碰巧Satelite的FK上也有一个唯一的索引。我的目标是为where子句使用卫星上的属性加载一个合并实体及其左右实体

我已经尝试了很多方法,但是我对Linq的词汇量很弱,我甚至不知道我要找的术语

var joinder = dbContext.Joinders
                .Include(j => j.Left)
                .Include(j => j.Right)
                .Include(j => j.Left.Satellites)
                .FirstOrDefault(s => s.Name == "Hubble");
这不起作用,因为FirstOrDefault子句没有用于分析名称的s上下文

var joinder = dbContext.Joinders
                .Include(j => j.Left)
                .Include(j => j.Right)
                .Include(j => j.Left.Satellites)
                .Select(j => j.Left.Satellites)
                .Where(s => s.Name == "Hubble");
这不起作用,因为Select输出的类型是
IQueryable
,这很容易混淆

var query = from j in dbContext.Joinders
    join l in dbContext.Lefts on j.LeftId equals l.Id
    join r in dbContext.Rights on j.RightId equals r.Id
    join s in dbContext.Satellites on l.Id equals s.LeftId
    where s.Name == "Hubble"
    select j;
这个查询编译并运行,但会将完全脱水的对象返回给我——我得到的joinerd引用的左属性和右属性都为null

var query = from j in dbContext.Joinders
    join l in dbContext.Lefts on j.LeftId equals l.Id
    join r in dbContext.Rights on j.RightId equals r.Id
    join s in dbContext.Satellites on l.Id equals s.LeftId
    where s.Name == "Hubble"
    select new Joinder
    {
        Left = l,
        Right = r,
        Left.Satellites = ...?
    };
这似乎不起作用,因为我似乎无法在自动初始值设定项中取消引用这些属性名

有人知道怎么做吗?基本上,我想搜索“实体框架多对多深度加载”,但我想不是每个人都会像我一样使用它。

试试这个

var joinders = dbContext.Joinders
                        .Include(j => j.Left)
                        .Include(j => j.Right)
                        .Include(j => j.Left.Satellites)
                        .Where(j => j.Left.Satellites.Any(s => s.Name == "Hubble");
这将返回所有连接到“左侧”的卫星名称为“哈勃”的合并。 我知道左边和右边都会被加载,但对于卫星,我不确定

var joinder = dbContext.Joinders
    .Include(j => j.Right)
    .Include(j => j.Left.Satellites)
    .FirstOrDefault(j => j.Left.Satellites.Any(s => s.Name == "Hubble"));
它返回至少有一个具有给定名称的卫星的第一个合并
.Include(j=>j.Left.Satellites)
也将包括
Left
实体(位于最后一个属性路径上的所有内容),因此不需要单独的
Include(j=>j.Left)

编辑


如果不想将相关的
卫星
合并
一起加载,只需将
.Include(j=>j.Left.Satellites)
替换为
。Include(j=>j.Left)
FirstOrDefault
中的谓词(取决于
Satellite
属性)仍然有效。

不需要包含
Satellites
?一个合并实体及其左侧和右侧实体。“选择”在没有包含的情况下可以工作。@GertArnold:是的,我没有仔细阅读这个问题。问题最后一段代码中的
Left.Satellites=…?
在我看来,他也想加载卫星。我在回答中添加了一句话。我确实不打算加载卫星实体,但由于解释上的差异而产生的对话是有帮助的,非常有启发性!有趣!那么在FirstOrDefault的上下文中,j.Left.Satellites解析为Satellite而不是Collection?这有点让人困惑,但我想我也看不出它还能起什么作用。谢谢FirstOrDefault就像在Sql中添加Select“Top 1”。我没有注意到卫星的“s”。检查我的更新