2023年了,有哪些 ORM 支持动态操作?

2023年了,有哪些 ORM 支持动态操作?FreeSql 提供 Where、GroupBy、OrderBy、ToList 等直接使用 SQL 片段的 API。

大家好,欢迎来到IT知识分享网。

2023年了,有哪些 ORM 支持动态操作?

FreeSql .NET ORM 支持 .NetFramework4.0+、.NetCore、Xamarin、MAUI、Blazor、以及还有说不出来的运行平台,因为代码**绿色无依赖**,支持新平台非常简单。目前单元测试数量:8500+,Nuget下载数量:1M+。使用最宽松的开源协议 MIT https://github.com/dotnetcore/FreeSql ,可以商用,文档齐全,甚至拿去卖钱也可以。

支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/ClickHouse/达梦/南大通用GBase/神通/人大金仓/翰高/华为GaussDB/MsAccess 等数据库,以及自定义适配其它数据库。

FreeSql 主要优势在于易用性上,基本是开箱即用,在不同数据库之间切换兼容性比较好,整体的功能特性如下:

  • 支持 CodeFirst 对比结构变化迁移、DbFirst 从数据库生成实体类;
  • 支持 丰富的表达式函数,独特的自定义解析;
  • 支持 批量添加、批量更新、BulkCopy、导航属性,贪婪加载、延时加载、级联保存、级联删除;
  • 支持 读写分离、分表分库,租户设计,分布式事务;
  • 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/神通/人大金仓/翰高/Clickhouse/MsAccess http://Ado.net 实现包,以及 Odbc 的专门实现包;

8000+个单元测试作为基调,支持10多数数据库,我们提供了通用Odbc理论上支持所有数据库,目前已知有群友使用 FreeSql 操作华为高斯、mycat、tidb 等数据库。安装时只需要选择对应的数据库实现包:

dotnet add packages FreeSql.Provider.Sqlite

动态操作

弱类型 CRUD

fsql.Insert<object>().AsType(实体类型)
  .AppendData(data)
  .ExecuteAffrows();

fsql.Update<object>().AsType(实体类型)
  .SetSource(data)
  .ExecuteAffrows();

fsql.Delete<object>().AsType(实体类型)
  .Where(a => (a as BaseEntity).Id == 1)
  .ExecuteAffrows();

//fsql.Select<object>()...

//或者仓储
var repo = fsql.GetRepository<object>();
repo.AsType(实体类型);

repo.Insert(..);
repo.Update(..);
repo.Delete(..);
repo.InsertOrUpdate(..);

提示:动态编译技术 https://natasha.dotnetcore.xyz/zh-Hans/docs/get_started/string-complie

字典 CUD

var dic = new Dictionary<string, object>();
dic.Add("id", 1);
dic.Add("name", "xxxx");

fsql.InsertDict(dic).AsTable("table1").ExecuteAffrows();
fsql.UpdateDict(dic).AsTable("table1").WherePrimary("id").ExecuteAffrows();
fsql.DeleteDict(dic).AsTable("table1").ExecuteAffrows();
fsql.InsertOrUpdateDict(dic).AsTable("table1").WherePrimary("id").ExecuteAffrows();

InsertDict/UpdateDict/DeleteDict/InsertOrUpdateDict 都支持批量操作,对应类型 List\<Dictionary\<string, object\>\>

动态条件

1、ISelect.Where(string sql) 使用原生条件:

fsql.Select<Region>().Where("a.id > 0") //提示:存在SQL注入安全问题

2、动态 Lambda 表达式

  • AndOr扩展方法 LambadaExpressionExtensions.cs
Expression<Func<Region, bool>> where = null;
where = where.And(b => b.Id > 10);
where = where.Or(b => b.Id == 1);
fsql.Select<Region>().Where(where).ToList();
//WHERE id > 10 OR id = 1

3、ISelect.WhereDynamicFilter 方法实现动态过滤条件(与前端交互),支持的操作符:

  • Contains/StartsWith/EndsWith/NotContains/NotStartsWith/NotEndsWith:包含/不包含,like ‘%xx%’,或者 like ‘xx%’,或者 like ‘%xx’
  • Equal/NotEqual:等于/不等于
  • GreaterThan/GreaterThanOrEqual:大于/大于等于
  • LessThan/LessThanOrEqual:小于/小于等于
  • Range:范围查询
  • DateRange:日期范围,有特殊处理 value[1] + 1
  • Any/NotAny:是否符合 value 中任何一项(直白的说是 SQL IN)
  • Custom:自定义解析
DynamicFilterInfo dyfilter = JsonConvert.DeserializeObject<DynamicFilterInfo>(@"
{
    ""Logic"": ""And"",
    ""Filters"":
    [
        { ""Field"": ""id"", ""Operator"": ""Equals"", ""Value"": 1 },
        {
            ""Logic"": ""Or"",
            ""Filters"":
            [
                { ""Field"": ""id"", ""Operator"": ""Equals"", ""Value"": 2 },
                { ""Field"": ""id"", ""Operator"": ""Equals"", ""Value"": 3 }
            ]
        }
    ]
}");
fsql.Select<Region>().WhereDynamicFilter(dyfilter).ToList();
//WHERE id = 1 AND (id = 2 OR id = 3)

《高效理解 FreeSql WhereDynamicFilter,深入了解设计初衷》

动态排序

1、ISelect.OrderBy(string sql) 使用原生排序:

fsql.Select<Region>().OrderBy("a.id desc") //提示:存在SQL注入安全问题

2、ISelect.OrderByPropertyName 使用属性名排序:

  • 支持导航属性,比如 OrderByPropertyName(“Parent.Code”)
  • 支持多表查询,比如 OrderByPropertyName(“b.Code”)

动态贪婪加载

1、ISelect.IncludeByPropertyName 方法实现动态贪婪加载,对应 Include/IncludeMany:

fsql.Select<Region>()
    .IncludeByPropertyName("Parent.Parent.Parent")
    .IncludeByPropertyName("Childs")

    .IncludeByPropertyName("Childs", then => then
        .IncludeByPropertyName("Parent.Parent")
        .IncludeByPropertyName("Parent.Childs"))
    .ToList();

2、List\<TDto\>.IncludeByPropertyName 扩展方法也实现了 OneToMany 动态贪婪加载:

非实体类型,也可以级联加载,他们不需要配置导航属性关系。

var dtos = fsql.Select<Region>().ToList<Dto>();

dtos.IncludeByPropertyName(
    orm: fsql, 
    property: "Childs", 
    where: "ParentId=Id", //临时关系
    take: 5, 
    select: "id,name",
    then => then.IncludeByPropertyName("Parent")
);

动态返回数据

1、ISelect.ToList 使用原生SQL返回数据:

List<(int, string)> list = fsql.Select<Region>()
    .ToList<(int, string)>("a.id,a.name") //提示:存在SQL注入安全问题

2、ISelect.ToDataTableByPropertyName 使用属性名返回数据:

DataTable dt = fsql.Select<Region>()
    .ToDataTableByPropertyName(new [] {
        "Parent.Code",
        "b.Id"
    });

动态片段

FreeSql 提供 Where(sql)、GroupBy(sql)、OrderBy(sql)、ToList(sql) 等直接使用 SQL 片段的 API。

使用这些 API 时请务必注意SQL注入安全问题。

不建议前端直接 POST SQL 到后端使用它们,而应该在后端做一层映射,例如:

var whereMapping = new Dictionary<string, string>
{
    ["where1"] = "a.id > {0}",
    ["where2"] = "len(a.name) > {0}"
};
var orderByMapping = new Dictionary<string, string>
{
    ["order1"] = "a.id asc, a.name desc",
    ["order2"] = "len(a.name) desc"
};

//假设前端 POST 内容是 postWhere=where1&postWhereValue=100&postOrder=order1
fsql.Select<Region>()
    .WhereIf(
        whereMapping.TryGetValue(postWhere, out var whereSql), 
        string.Format(whereSql, postWhereValue)
    )
    .OrderBy(
        orderByMapping.TryGetValue(postOrder, out var orderSql), 
        orderSql
    )

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/62338.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信