gpt4 book ai didi

c# - Entity Framework 中的 "Include"链接

转载 作者:太空宇宙 更新时间:2023-11-03 15:47:06 25 4
gpt4 key购买 nike

不确定标题中的术语是否正确,但对下述特定行为有疑问。

给定:

public class FooBar
{
// etc
public virtual ICollection<Foo> Foos { get; set; }
public virtual ICollection<Bar> Bars { get; set; }
}

public class Foo
{
}

public class Bar
{
}

public class FooBarRepo
{
private readonly EntitiesContext _context;

public FooBarRepo()
{
this._context = new EntitiesContext();
}

public IQueryable<FooBar> GetIncludeFoo()
{
return this
._context
.FooBars
.Include(i => i.Foos);
}

public IQueryable<FooBar> GetIncludeBar()
{
return this
._context
.FooBars
.Include(i => i.Bars);
}
}

我没有测试台来确认这种行为,所以想确保我的解释/内存是正确的——但如果我要这样定义一个额外的函数:

public IQueryable<FooBar> GetIncludeBarChainedWithGetIncludeFoo()
{
return this
.GetIncludeFoo()
.Include(i => i.Bars);
}

我似乎记得在调用 GetIncludeBarChainedWithGetIncludeFoo() 时,我只得到了我的 Bars,而不是我期望的额外的 FoosGetIncludeFoo() 的调用是调用的一部分。

可以确认/解释这种行为吗?

最佳答案

免责声明:自从我使用 EF 以来,它可能已经发生了变化。我在 EF 4.x 的水平上写作。以后的版本可能会添加一些更好的支持来向上传播包含查询,我实际上从未检查过。但我对此有些怀疑。所以,请不要把所有这些都当作绝对真理,一定要自己尝试。例如,我不记得 GroupBy 是否真的破坏了包含,但我确信 Select 会导致匿名类型的投影 - 确实如此。


不,在您的示例中,它会起作用。

在您的示例中,当调用 GetIncludeBarChainedWithGetIncludeFoo 时,您的代码实际上调用/构建以下序列/查询:

    // from GetIncludeFoo
return this
._context
.FooBars
.Include(i => i.Foos)
// from GetIncludeBarChainedWithGetIncludeFoo
.Include(i => i.Bars);

这将 100% 地按照您的想法运行:它将返回 FooBars,同时预加载了 Foos 和 Bars。简单的链接绝对没问题,就像您也可以这样做:

    // from GetIncludeFoo
return this
._context
.FooBars
.Include("Foos")
.Include("Bars");

但是,当您像在示例中所做的那样将这两个包含拆分为多个方法时,就会出现一个微妙的陷阱。让我们看看:

    return this
.GetIncludeFoo() // let's say they all are extensions just for clarity
.DoSomeMyOtherThings()
.GetIncludeBar()

如果“DoSomeMyOtherThings”做出任何会导致查询改变其形状并松开其与特定表的紧密绑定(bind)(如投影)的操作,那么 IncludeBar 将失败,即使它看起来还不错。所有包含(定义要提取的新源)都应在任何其他操作之前。

    return this
.GetIncludeFoo() // let's say they all are extensions just for clarity
.GetIncludeBar()
.DoSomeMyOtherThings()

这可能看起来很明显,但是当您开始将 includes/wheres/selects/groupbys 包装到漂亮的方法中,然后开始将方法混合在一起时,很容易忘记这一点:

    return this
.GetFooThatAre("Green")
.GetBestBarForEachFoo()
.GetBuzzFromBar()

第一种方法将能够包含“Foos”。第二种方法可能会成功包含“条”。然而,由于第二种方法中隐藏的 groupby 和/或投影,最后一种可能无法包含“Buzz”。

即使使用漂亮的包装器,查询仍然必须是:

    return this
.GetIncludeFoo()
.GetIncludeBar()
.GetIncludeBuzz()
.GetFooThatAre("Green")
.GetBestBarForEachFoo()
.GetBuzzFromBar()

或类似的东西。

关于c# - Entity Framework 中的 "Include"链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27692547/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com