【问题标题】:Load* POCO references using OrmLite and SQL使用 OrmLite 和 SQL 加载* POCO 引用
【发布时间】:2016-11-18 23:25:08
【问题描述】:

我有几个关于 ServiceStack.OrmLite 的 POCO 参考功能的问题。

  1. 当使用Load*() API 获取带有引用的 POCO 时,它是在内部生成并运行单个 SQL 查询(使用适当的 JOIN)来返回 POCO 及其引用,还是运行单独的查询(对于 POCO,然后每个参考一个)?

  2. 有没有办法让Load*() API 接受自定义 SQL 查询(而不是 SqlExpression),并且仍然能够自动加载引用,而不必为每个对象调用 LoadReferences() ?

我正在尝试指定一个自定义 SQL 语句并返回一个带有预加载引用的 POCO 列表,希望在后台运行单个查询。

希望有人能提供一些见解。

【问题讨论】:

    标签: servicestack ormlite-servicestack


    【解决方案1】:

    Load References 加载 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 个用于加载 Tracks 子引用的查询。

    【讨论】:

    • 谢谢@mythz。主表查询是复杂且资源密集型的,所以我最终使用Select API 执行它,然后对来自主查询的唯一 ID 的引用表执行单独的查询,最后合并两个结果集。在我的情况下,它比 LoadSelect 更快、更优化,后者将主查询作为参考查询重新运行。我想对这种方法的一个警告是,主查询中唯一 ID 的数量必须合理,以免超过 IN 子句的参数限制。
    猜你喜欢
    • 2014-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    相关资源
    最近更新 更多