This commit is contained in:
28810 2018-12-28 12:14:14 +08:00
parent 0689696766
commit 3ed1213865
8 changed files with 181 additions and 8 deletions

97
Docs/1 简介.md Normal file
View File

@ -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<Blog>
.Where(b => b.Rating > 3)
.OrderBy(b => b.Url)
.ToList();
```
## 插入
```csharp
var blog = new Blog { Url = "http://sample.com" };
blog.BlogId = (int)fsql.Insert<Blog>()
.AppendData(blog)
.ExecuteIdentity();
```
## 更新
```csharp
fsql.Update<Blog>()
.Set(b => b.Url, "http://sample2222.com")
.Where(b => b.Url == "http://sample.com")
.ExecuteAffrows();
```
## 删除
```csharp
fsql.Delete<Blog>()
.Where(b => b.Url == "http://sample.com")
.ExecuteAffrows();
```
## 后续步骤
有关介绍性教程,请参阅 [FreeSql 入门]()。

28
Docs/2 入门.md Normal file
View File

@ -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 应用
- * 新建数据库
- * 现有数据库

0
Docs/2.1 安装FreeSql Normal file
View File

View File

@ -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"); 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返回数据 ### 执行SQL返回数据

View File

@ -25,7 +25,10 @@ namespace FreeSql.Tests {
.Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100)
.OrderBy(a => a.Key.tt2) .OrderBy(a => a.Key.tt2)
.OrderByDescending(a => a.Count()) .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 }; var sss = new[] { 1, 2, 3 };

View File

@ -26,12 +26,27 @@ namespace FreeSql.Internal {
case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString); case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString);
case ExpressionType.Constant: case ExpressionType.Constant:
var constExp = exp as ConstantExpression; 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); field.Append(", ").Append(parent.DbField);
if (index >= 0) field.Append(" as").Append(++index); if (index >= 0) field.Append(" as").Append(++index);
return false; return false;
case ExpressionType.Call: 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); field.Append(", ").Append(parent.DbField);
if (index >= 0) field.Append(" as").Append(++index); if (index >= 0) field.Append(" as").Append(++index);
return false; return false;

View File

@ -78,10 +78,6 @@ namespace FreeSql.MySql.Curd {
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret); return ret; } public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.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); 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<T1, T2> : FreeSql.Internal.CommonProvider.Select2Provider<T1, T2> 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<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
//}
class MySqlSelect<T1, T2, T3> : FreeSql.Internal.CommonProvider.Select3Provider<T1, T2, T3> where T1 : class where T2 : class where T3 : class { class MySqlSelect<T1, T2, T3> : FreeSql.Internal.CommonProvider.Select3Provider<T1, T2, T3> 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 MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm); public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);

View File

@ -1,6 +1,14 @@
# FreeSql # FreeSql
打造 .NETCore 最方便的ormdbfirst codefirst混合使用codefirst模式下的开发阶段建好实体不用执行任何就能创建表和修改字段dbfirst模式下提供api+模板自定义生成代码作者提供了3种模板。目前仍然在开发中可以持续关注或者参与给出宝贵意见QQ群4336577 FreeSql 是轻量化、可扩展和跨平台版的 .NETStandard 数据访问技术实现。
FreeSql 可用作对象关系映射程序 (O/RM),以便于开发人员能够使用 .NETStandard 对象来处理数据库,不必经常编写大部分数据访问代码。
FreeSql 支持 MySql/SqlServer/PostgreSQL 数据库技术实现。
FreeSql 打造 .NETCore 最方便的 ORMdbfirst codefirst混合使用codefirst模式下的开发阶段建好实体不用执行任何操作就能创建表和修改字段dbfirst模式下提供api+模板自定义生成代码作者提供了3种模板。
FreeSql 目前仍处在测试阶段您可以持续关注或者参与给出宝贵意见QQ群4336577
* [《CodeFirst 快速开发文档》](Docs/codefirst.md) * [《CodeFirst 快速开发文档》](Docs/codefirst.md)
@ -24,6 +32,13 @@ IFreeSql fsql = new FreeSql.FreeSqlBuilder()
``` ```
# 实体 # 实体
FreeSql 使用模型执行数据访问,模型由实体类表示数据库表或视图,用于查询和保存数据。 有关详细信息,请参阅创建模型。
可从现有数据库生成实体模型,提供 IDbFirst 生成实体模型。
或者手动创建模型,基于模型创建或修改数据库,提供 ICodeFirst 同步结构的 API甚至可以做到开发阶段自动同步
```csharp ```csharp
[Table(Name = "tb_topic")] [Table(Name = "tb_topic")]
class Topic { class Topic {
@ -65,6 +80,15 @@ List<匿名类型> t4 = fsql.Select<Topic>().Where(a => a.Id > 0).ToList(a => ne
//返回元组 //返回元组
List<(int, string)> t5 = fsql.Select<Topic>().Where(a => a.Id > 0).ToList<(int, string)>("id, title"); List<(int, string)> t5 = fsql.Select<Topic>().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 ```csharp