mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
update
This commit is contained in:
parent
0689696766
commit
3ed1213865
97
Docs/1 简介.md
Normal file
97
Docs/1 简介.md
Normal 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
28
Docs/2 入门.md
Normal 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
0
Docs/2.1 安装FreeSql
Normal 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返回数据
|
||||||
|
@ -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 };
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
26
readme.md
26
readme.md
@ -1,6 +1,14 @@
|
|||||||
# FreeSql
|
# 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)
|
* [《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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user