我对ServiceStack.OrmLite的POCO参考功能有几个疑问。
使用estimatedTimeOfArrival
API获取带引用的POCO时,它是否在内部生成&运行单个SQL查询(使用适当的JOIN)返回POCO及其引用,或者它是否运行单独的查询(一个用于POCO,然后一个用于每个引用)?
有没有办法让estimatedTimeOfArrival
API接受自定义SQL查询(而不是SqlExpression),并且仍然能够自动加载引用,而不必调用{{1}每个对象?
我试图指定一个自定义SQL语句,并返回一个POCO列表,其中包含预先加载的引用,希望在引擎盖下运行单个查询。
希望有人能够提供一些见解。
答案 0 :(得分:3)
加载引用加载 1查询以加载主表, 1查询加载子引用,而不管子引用有多少行。
通过查看使用ConsoleLogFactory
时记录到控制台输出的SQL Generated,您可以看到生成的SQL。例如,LoadSelect
example you can run on Gistlyn及其控制台输出:
public class Artist
{
public int Id { get; set; }
public string Name { get; set; }
[Reference]
public List<Track> Tracks { get; set; }
public override string ToString() => Name;
}
public class Track
{
[AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
public int ArtistId { get; set; }
public string Album { get; set; }
public int Year { get; set; }
public override string ToString() => Name;
}
var oldestTracks = db.Select(db.From<Track>()
.Where(x => Sql.In(x.Year, db.From<Track>().Select(y => Sql.Min(y.Year)))));
"Oldest Tracks: {0}".Print(oldestTracks.Dump());
var oldestTrackIds = oldestTracks.Map(x => x.Id);
var earliestArtistsWithRefs = db.LoadSelect(db.From<Artist>()
.Where(a => oldestTracks.Map(t => t.ArtistId).Contains(a.Id)));
"Earliest Artists: {0}".Print(earliestArtistsWithRefs.Dump());
控制台输出:
DEBUG: SQL: SELECT "Id", "Name"
FROM "Artist"
WHERE "Id" In (@0,@1)
PARAMS: @0=3, @1=4
DEBUG: SQL: SELECT "Id", "Name", "ArtistId", "Album", "Year" FROM "Track" WHERE "ArtistId" IN (SELECT "Artist"."Id"
FROM "Artist"
WHERE "Id" In (@0,@1))
PARAMS: @0=3, @1=4
Earliest Artists: [
{
Id: 3,
Name: Nirvana,
Tracks:
[
{
Id: 5,
Name: Smells Like Teen Spirit,
ArtistId: 3,
Album: Nevermind,
Year: 1991
},
{
Id: 6,
Name: Heart-Shaped Box,
ArtistId: 3,
Album: In Utero,
Year: 1993
}
]
},
{
Id: 4,
Name: Pearl Jam,
Tracks:
[
{
Id: 7,
Name: Alive,
ArtistId: 4,
Album: Ten,
Year: 1991
},
{
Id: 8,
Name: Daughter,
ArtistId: 4,
Album: Vs,
Year: 1993
}
]
}
]
您可以在其中看到2个查询,1个用于加载主表的查询和1个用于加载“跟踪子”引用的查询。