FreeSql (二十一)查詢返回數據

FreeSql 採用 ExpressionTree 優化讀取速讀,若是懂技術的你必定知道 .NETCore 技術下除了原生代碼,最快就是 Emit 和 ExpressionTree。html

項目在初期使用的反射+緩存,雖然 .NETCore 優化了反射性能,但通過與Dapper性能測試對比以後,發現仍然有必定差距,改爲 ExpresstionTree 後才與 Dapper 性能至關。sql

FreeSql 支持的類型較多,實現 ExpressionTree 的複雜度較大,有興趣的朋友能夠翻閱源代碼。api

IFreeSql fsql = new FreeSql.FreeSqlBuilder()
    .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
    .Build();

[Table(Name = "tb_topic")]
class Topic {
    [Column(IsIdentity = true, IsPrimary = true)]
    public int Id { get; set; }
    public int Clicks { get; set; }
    public int TestTypeInfoGuid { get; set; }
    public TestTypeInfo Type { get; set; }
    public string Title { get; set; }
    public DateTime CreateTime { get; set; }
}
class TestTypeInfo {
    public int Guid { get; set; }
    public int ParentId { get; set; }
    public TestTypeParentInfo Parent { get; set; }
    public string Name { get; set; }
}
class TestTypeParentInfo {
    public int Id { get; set; }
    public string Name { get; set; }
}

ISelect<Topic> select => fsql.Select<Topic>();

返回單條記錄

Topic t1 = select.Where(a => a.Id == 1).ToOne();

FreeSql有一個約定,ToOne 永遠返回 null 或 有數據的實體對象,ToList 永遠返回非 null 的 List<實體類型>緩存

返回 List

List<Topic> t1 = select.Where(a => a.Id > 0).Skip(100).Limit(200).ToList();

返回 List + 導航屬性的數據

List<Topic> t2 = select.LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid).ToList();
//此時會返回普通字段 + 導航對象 Type 的數據

指定字段返回

//返回一個字段
List<int> t3 = select.Where(a => a.Id > 0).ToList(a => a.Id);

//返回匿名類
List<匿名類> t4 = select.Where(a => a.Id > 0).ToList(a => new { a.Id, a.Title });

//返回元組
List<(int, string)> t5 = select.Where(a => a.Id > 0).ToList<(int, string)>("id, title");

//返回指定映射字段
List<(int, string)> t6 = select.Where(a => a.Id > 0).ToList<Dto>();

//返回SQL字段
List<匿名類> t7 = select.Where(a => a.Id > 0).Skip(100).Limit(200)
    .ToList(a => new {
        a.Id,
        a.Title,
        cstitle = "substr(a.title, 0, 2)", //將 substr(a.title, 0, 2) 做爲查詢字段
        csnow = Convert.ToDateTime("now()"), //將 now() 做爲查詢字段
        //奇思妙想:怎麼查詢開窗函數的結果
    });

//返回更爲複雜的結構
List<匿名類> t8 = select.From<TestTypeInfo, TestTypeParentInfo>((s, b, c) => s
    .InnerJoin(a => a.TypeGuid == b.Guid)
    .LeftJoin(a => c.Id == b.ParentId)
    .Where(a => b.Name != "xxx")).ToList((a, b, c) => new {
        a.Id,
        a.Title,
        a.Type,
        ccc = new { a.Id, a.Title },
        tp = a.Type,
        tp2 = new {
            a.Id,
            tp2 = a.Type.Name
        },
        tp3 = new {
            a.Id,
            tp33 = new {
                a.Id
            }
        }
    });

執行SQL

class xxx {
    public int Id { get; set; }
    public string Path { get; set; }
    public string Title2 { get; set; }
}

List<xxx> t9 = fsql.Ado.Query<xxx>("select * from song");
List<(int, string ,string)> t10 = fsql.Ado.Query<(int, string, string)>("select * from song");
List<dynamic> t11 = fsql.Ado.Query<dynamic>("select * from song");

巧用AsTable

var t12 = fsql.Select<User>()
    .AsTable((a, b) => "(select * from tb_topic where clicks > 10)")
    .Page(1, 10).ToList()

ToChunk

執行查詢,分塊返回數據,可減小內存開銷。好比讀取10萬條數據,每次返回100條處理。app

var testlist1 = fsql.Select<Song>().OrderBy(a => a.Id).ToList();
var testlist2 = new List<Song>();
fsql.Select<Song>().OrderBy(a => a.Id).ToChunk(100, list =>
{
    testlist2.AddRange(list);
});
//這裏示範,最終 testlist1 與 testlist2 返回的數據相同。

API

方法 返回值 參數 描述
ToSql string 返回即將執行的SQL語句
ToList List 執行SQL查詢,返回 T1 實體全部字段的記錄,若存在導航屬性則一塊兒查詢返回,記錄不存在時返回 Count 爲 0 的列表
ToList<Dto> List<Dto> Lambda 執行SQL查詢,返回指定字段或Dto映射的記錄,記錄不存在時返回 Count 爲 0 的列表
ToList<T> List<T> string field 執行SQL查詢,返回 field 指定字段的記錄,並以元組或基礎類型(int,string,long)接收,記錄不存在時返回 Count 爲 0 的列表
ToOne T1 執行SQL查詢,返回 T1 實體全部字段的第一條記錄,記錄不存在時返回 null
ToChunk <空> int size, Action<List<T1>> done 執行SQL查詢,分塊返回數據,可減小內存開銷。好比讀取10萬條數據,每次返回100條處理。
Any bool 執行SQL查詢,是否有記錄
Sum T Lambda 指定一個列求和
Min T Lambda 指定一個列求最小值
Max T Lambda 指定一個列求最大值
Avg T Lambda 指定一個列求平均值

系列文章導航

相關文章
相關標籤/搜索