1

我有一个多对多的关系(对于这个例子,“左”、“右”和“连接器”)和另一个实体“卫星”,它键入“左”。碰巧 Sattelite 的 FK 上也有一个唯一索引。我的目标是加载一个 Joinder 实体及其左右实体,使用 Satellite 上的属性作为 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<Collection<Satellite>>令人困惑。

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;

此查询编译并运行,但将完全脱水的对象返回给我——我返回的 Joinder 引用的 Left 和 Right 属性均为空。

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 = ...?
    };

这似乎不起作用,因为我似乎无法在自动初始化程序中取消引用这些属性名称。

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

4

2 回答 2

2
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)

编辑

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

于 2013-10-05T11:58:10.150 回答
0

尝试这个

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");

这将返回所有连接到“左”的卫星的名称为“哈勃”的所有连接器。我知道 Left 和 Right 将被急切加载,但对于 Satellites,我不确定。

于 2013-10-05T11:42:14.547 回答