只是有條件地在查詢表達式中添加Include(f => f.Bars)。就像這樣:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Data.SqlClient;
using System.Linq;
using System.Threading.Tasks;
namespace ConsoleApp8
{
public class Bar
{
public Guid Id { get; set; }
public string SomeBar { get; set; }
}
public class Foo
{
public Guid Id { get; set; }
public string FooString { get; set; }
public IList<Bar> Bars { get; set; }
}
class Db: DbContext
{
public DbSet<Foo> Foos { get; set; }
public DbSet<Bar> Bar { get; set; }
public async Task<Foo> GetFooByIdAsync(Guid id, bool includeBars)
{
var query = (IQueryable<Foo>)Foos.AsNoTracking();
if (includeBars)
{
query = query.Include(f => f.Bars);
}
query = query.Where(f => f.Id == id);
var results = await query.ToListAsync();
return results.FirstOrDefault();
}
}
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<Db>());
using (var db = new Db())
{
db.Database.Initialize(false);
db.Database.Log = m => Console.WriteLine(m);
var r1 = db.GetFooByIdAsync(Guid.Empty, false).Result;
var r2 = db.GetFooByIdAsync(Guid.Empty, true).Result;
}
Console.WriteLine("Hit any key to exit");
Console.ReadKey();
}
}
}
輸出
Opened connection asynchronously at 9/11/2017 11:37:26 PM -05:00
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[FooString] AS [FooString]
FROM [dbo].[Foos] AS [Extent1]
WHERE [Extent1].[Id] = @p__linq__0
-- p__linq__0: '00000000-0000-0000-0000-000000000000' (Type = Guid, IsNullable = false)
-- Executing asynchronously at 9/11/2017 11:37:26 PM -05:00
-- Completed in 22 ms with result: SqlDataReader
Closed connection at 9/11/2017 11:37:26 PM -05:00
Opened connection asynchronously at 9/11/2017 11:37:26 PM -05:00
SELECT
[Project1].[C1] AS [C1],
[Project1].[Id] AS [Id],
[Project1].[FooString] AS [FooString],
[Project1].[C2] AS [C2],
[Project1].[Id1] AS [Id1],
[Project1].[SomeBar] AS [SomeBar]
FROM (SELECT
[Extent1].[Id] AS [Id],
[Extent1].[FooString] AS [FooString],
1 AS [C1],
[Extent2].[Id] AS [Id1],
[Extent2].[SomeBar] AS [SomeBar],
CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2]
FROM [dbo].[Foos] AS [Extent1]
LEFT OUTER JOIN [dbo].[Bars] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Foo_Id]
WHERE [Extent1].[Id] = @p__linq__0
) AS [Project1]
ORDER BY [Project1].[Id] ASC, [Project1].[C2] ASC
-- p__linq__0: '00000000-0000-0000-0000-000000000000' (Type = Guid, IsNullable = false)
-- Executing asynchronously at 9/11/2017 11:37:26 PM -05:00
-- Completed in 2 ms with result: SqlDataReader
Closed connection at 9/11/2017 11:37:26 PM -05:00
Hit any key to exit
你有沒有看到這個帖子:https://stackoverflow.com/questions/3718400/conditional-eager-loading? –
@DavidTansey有很多帖子要過濾,如果你沒有得到正確的搜索詞,他們不會出現。不,我沒有看到那個。基於這個答案,我認爲只要你foreach迭代iqueryable,它會加載數據,這是正確的嗎?還有,不同於調用'.Select(f => ...);'在我的例子中? –
對不起 - 我沒有注意到你在你的問題中顯示了一個可行的方法。就鏈接帖子中的'foreach'與您的代碼而言,我對此的理解完全符合您所描述的內容。我唯一要補充的是:如果在比較看似等價的語法時,如果您的問題/情況進一步擴展爲與性能相關的問題 - 請花時間使用SQL事件探查器檢查生成的查詢,看看它們是否真的是等效的。 EF有時會生成「有趣」的SQL。 –