From 3ed1213865e846018b68c069bf54b1a3558508f3 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 28 Dec 2018 12:14:14 +0800 Subject: [PATCH] update --- Docs/1 简介.md | 97 ++++++++++++++++++++++++++++ Docs/2 入门.md | 28 ++++++++ Docs/2.1 安装FreeSql | 0 Docs/select.md | 10 +++ FreeSql.Tests/UnitTest1.cs | 5 +- FreeSql/Internal/CommonExpression.cs | 19 +++++- FreeSql/MySql/Curd/MySqlSelect.cs | 4 -- readme.md | 26 +++++++- 8 files changed, 181 insertions(+), 8 deletions(-) create mode 100644 Docs/1 简介.md create mode 100644 Docs/2 入门.md create mode 100644 Docs/2.1 安装FreeSql diff --git a/Docs/1 简介.md b/Docs/1 简介.md new file mode 100644 index 00000000..c9c021af --- /dev/null +++ b/Docs/1 简介.md @@ -0,0 +1,97 @@ +# FreeSql 简介 + +FreeSql 是轻量化、可扩展和跨平台版的 .NETStandard 数据访问技术实现。 + +FreeSql 可用作对象关系映射程序 (O/RM),以便于开发人员能够使用 .NETStandard 对象来处理数据库,不必经常编写大部分数据访问代码。 + +FreeSql 支持 MySql/SqlServer/PostgreSQL 数据库技术实现。 + +## 模型 + +FreeSql 使用模型执行数据访问,模型由实体类表示数据库表或视图,用于查询和保存数据。 有关详细信息,请参阅创建模型。 + +可从现有数据库生成实体模型,提供 IDbFirst 生成实体模型。 + +或者手动创建模型,基于模型创建或修改数据库,提供 ICodeFirst 同步结构的 API(甚至可以做到开发阶段自动同步)。 + +```csharp +using FreeSql.DataAnnotations; +using System; + +public class Blog +{ + [Column(IsIdentity = true, IsPrimary = true)] + public int BlogId { get; set; } + public string Url { get; set; } + public int Rating { get; set; } +} + +public class Post +{ + public int PostId { get; set; } + public string Title { get; set; } + public string Content { get; set; } + + public int BlogId { get; set; } + public Blog Blog { get; set; } +} +``` + +## 声明 + +```csharp +var connstr = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;" + + "Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10"; + +IFreeSql fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.MySql, connstr) + .UseSlave("connectionString1", "connectionString2") //使用从数据库,支持多个 + + .UseLogger(null) //使用日志,不指定默认输出控制台 ILogger + .UseCache(null) //使用缓存,不指定默认使用内存 IDistributedCache + + .UseAutoSyncStructure(true) //自动同步实体结构到数据库 + .UseSyncStructureToLower(true) //转小写同步结构 + .Build(); +``` + +注意: IFreeSql 在项目中应以单例声明,而不是在每次使用的时候创建。 + +## 查询 + +```csharp +var blogs = fsql.Select + .Where(b => b.Rating > 3) + .OrderBy(b => b.Url) + .ToList(); +``` + +## 插入 + +```csharp +var blog = new Blog { Url = "http://sample.com" }; +blog.BlogId = (int)fsql.Insert() + .AppendData(blog) + .ExecuteIdentity(); +``` + +## 更新 + +```csharp +fsql.Update() + .Set(b => b.Url, "http://sample2222.com") + .Where(b => b.Url == "http://sample.com") + .ExecuteAffrows(); +``` + +## 删除 + +```csharp +fsql.Delete() + .Where(b => b.Url == "http://sample.com") + .ExecuteAffrows(); +``` + +## 后续步骤 + +有关介绍性教程,请参阅 [FreeSql 入门]()。 diff --git a/Docs/2 入门.md b/Docs/2 入门.md new file mode 100644 index 00000000..00857ee9 --- /dev/null +++ b/Docs/2 入门.md @@ -0,0 +1,28 @@ +# FreeSql 入门 + +## 安装 + +FreeSql 是一个 .NET Standard 2.0 库,支持 .NET Framework 4.6.1 或 .NET Core 或更高版本的应用程序。 + +```shell +dotnet add package FreeSql +``` + +或者 + +```shell +Install-Package FreeSql +``` + +## 入门教程 + +FreeSql 可基于现有数据库创建模型,也可基于模型创建数据库。 提供的教程演示了这两种方法。 + +* .NET Core 控制台应用 + +- * 新建数据库 + +* ASP.NET Core 应用 + +- * 新建数据库 +- * 现有数据库 \ No newline at end of file diff --git a/Docs/2.1 安装FreeSql b/Docs/2.1 安装FreeSql new file mode 100644 index 00000000..e69de29b diff --git a/Docs/select.md b/Docs/select.md index 60e0ffbb..5766cf05 100644 --- a/Docs/select.md +++ b/Docs/select.md @@ -146,6 +146,16 @@ List<匿名类> t4 = select.Where(a => a.Id > 0).Skip(100).Limit(200).ToList(a = //返回元组 List<(int, string)> t5 = select.Where(a => a.Id > 0).Skip(100).Limit(200).ToList<(int, string)>("id, title"); + +//返回SQL字段 +List<匿名类> t4 = 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() 作为查询字段 + //奇思妙想:怎么查询开窗函数的结果 + }); ``` ### 执行SQL返回数据 diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 8447389e..48ed03da 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -25,7 +25,10 @@ namespace FreeSql.Tests { .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) .OrderBy(a => a.Key.tt2) .OrderByDescending(a => a.Count()) - .ToSql(a => new { a.Key.tt2, cou1 = a.Count(), arg1 = a.Avg(a.Key.mod4) }); + .ToSql(a => new { a.Key.tt2, cou1 = a.Count(), arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + }); var sss = new[] { 1, 2, 3 }; diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index e946e48d..d9442500 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -26,12 +26,27 @@ namespace FreeSql.Internal { case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString); case ExpressionType.Constant: var constExp = exp as ConstantExpression; - parent.DbField = _common.FormatSql("{0}", constExp?.Value); + //处理自定义SQL语句,如: ToList(new { + // ccc = "now()", + // partby = "sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)" + //}),有缺点即 ccc partby 接受类型都是 string,可配合 Convert.ToXxx 类型转换,请看下面的兼容 + parent.DbField = constExp.Type.FullName == "System.String" ? (constExp.Value?.ToString() ?? "NULL") : _common.FormatSql("{0}", constExp?.Value); field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(" as").Append(++index); return false; case ExpressionType.Call: - parent.DbField = ExpressionLambdaToSql(exp, _tables, null, getSelectGroupingMapString, SelectTableInfoType.From, true); + var callExp = exp as MethodCallExpression; + //处理自定义SQL语句,如: ToList(new { + // ccc = Convert.ToDateTime("now()"), + // partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + //}) + if (callExp.Method?.DeclaringType.FullName == "System.Convert" && + callExp.Method.Name.StartsWith("To") && + callExp.Arguments[0].NodeType == ExpressionType.Constant && + callExp.Arguments[0].Type.FullName == "System.String") + parent.DbField = (callExp.Arguments[0] as ConstantExpression).Value?.ToString() ?? "NULL"; + else + parent.DbField = ExpressionLambdaToSql(exp, _tables, null, getSelectGroupingMapString, SelectTableInfoType.From, true); field.Append(", ").Append(parent.DbField); if (index >= 0) field.Append(" as").Append(++index); return false; diff --git a/FreeSql/MySql/Curd/MySqlSelect.cs b/FreeSql/MySql/Curd/MySqlSelect.cs index 619131b7..2fce182b 100644 --- a/FreeSql/MySql/Curd/MySqlSelect.cs +++ b/FreeSql/MySql/Curd/MySqlSelect.cs @@ -78,10 +78,6 @@ namespace FreeSql.MySql.Curd { public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect(_orm, _commonUtils, _commonExpression, null); MySqlSelect.CopyData(this, ret); return ret; } public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); } - //class MySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T1 : class where T2 : class { - // public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } - // public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); - //} class MySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T1 : class where T2 : class where T3 : class { public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } public override string ToSql(string field = null) => MySqlSelect.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); diff --git a/readme.md b/readme.md index 5c09c528..d380a217 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,14 @@ # FreeSql -打造 .NETCore 最方便的orm,dbfirst codefirst混合使用,codefirst模式下的开发阶段,建好实体不用执行任何,就能创建表和修改字段,dbfirst模式下提供api+模板,自定义生成代码,作者提供了3种模板。目前仍然在开发中,可以持续关注或者参与,给出宝贵意见,QQ群:4336577 +FreeSql 是轻量化、可扩展和跨平台版的 .NETStandard 数据访问技术实现。 + +FreeSql 可用作对象关系映射程序 (O/RM),以便于开发人员能够使用 .NETStandard 对象来处理数据库,不必经常编写大部分数据访问代码。 + +FreeSql 支持 MySql/SqlServer/PostgreSQL 数据库技术实现。 + +FreeSql 打造 .NETCore 最方便的 ORM,dbfirst codefirst混合使用,codefirst模式下的开发阶段,建好实体不用执行任何操作,就能创建表和修改字段,dbfirst模式下提供api+模板,自定义生成代码,作者提供了3种模板。 + +FreeSql 目前仍处在测试阶段,您可以持续关注或者参与给出宝贵意见,QQ群:4336577 * [《CodeFirst 快速开发文档》](Docs/codefirst.md) @@ -24,6 +32,13 @@ IFreeSql fsql = new FreeSql.FreeSqlBuilder() ``` # 实体 + +FreeSql 使用模型执行数据访问,模型由实体类表示数据库表或视图,用于查询和保存数据。 有关详细信息,请参阅创建模型。 + +可从现有数据库生成实体模型,提供 IDbFirst 生成实体模型。 + +或者手动创建模型,基于模型创建或修改数据库,提供 ICodeFirst 同步结构的 API(甚至可以做到开发阶段自动同步)。 + ```csharp [Table(Name = "tb_topic")] class Topic { @@ -65,6 +80,15 @@ List<匿名类型> t4 = fsql.Select().Where(a => a.Id > 0).ToList(a => ne //返回元组 List<(int, string)> t5 = fsql.Select().Where(a => a.Id > 0).ToList<(int, string)>("id, title"); + +//返回SQL字段 +List<匿名类> t4 = 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() 作为查询字段 + //奇思妙想:怎么查询开窗函数的结果 + }); ``` ### 联表之一:使用导航属性 ```csharp