update

28810
2020-02-28 09:32:21 +08:00
parent 7d91a96e0e
commit 36b28eb773
12 changed files with 97 additions and 95 deletions

@@ -1,4 +1,4 @@
FreeSql 提供使用 Fluent Api 在外部配置实体的数据库特性Fluent Api 的方法命名与特性名保持一致,如下:
```csharp
fsql.CodeFirst
@@ -12,11 +12,27 @@ fsql.CodeFirst
a.Property(b => b.Id).Name("Id22").IsIdentity(true);
a.Property(b => b.name).DbType("varchar(100)").IsNullable(true);
});
//以下为实体类
class TestFluenttb1
{
public int Id { get; set; }
public string name { get; set; } = "defaultValue";
}
[Table(Name = "cccccdddwww")]
class TestFluenttb2
{
public int Id { get; set; }
public string name { get; set; } = "defaultValue";
}
```
最好在程序初始化执行,并且这段配置最好只执行一次,避免性能损耗。
> fsql 是一个 IFreeSql 对象
FluentApi 的命名与特性保持一致,有关说明请移步参考:[《实体特性说明》](https://github.com/2881099/FreeSql/wiki/%e5%ae%9e%e4%bd%93%e7%89%b9%e6%80%a7)
> 这段配置尽量只执行一次,避免性能损耗
参考:[《实体特性说明》](https://github.com/2881099/FreeSql/wiki/%e5%ae%9e%e4%bd%93%e7%89%b9%e6%80%a7)
> v1.1 增加扩展包 [FreeSql.Extensions.EfCoreFluentApi](https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.EfCoreFluentApi),方便 EfCore 使用者过渡,使用方法接近 EfCore

@@ -1,4 +1,4 @@
FreeSql 是一个功能强大的对象关系映射程序(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.0+QQ群4336577
FreeSql是一个功能强大的 .NET ORM 功能库,支持 .NetFramework 4.0+、.NetCore 2.1+、Xamarin 等支持 NetStandard 所有运行平台。QQ群4336577
## 模型

@@ -8,12 +8,9 @@ class Topic {
[Column(IsIdentity = true, IsPrimary = true)]
public int Id { get; set; }
public int Clicks { get; set; }
public int TestTypeInfoGuid { get; set; }
public string Title { get; set; }
public DateTime CreateTime { get; set; }
}
ISelect<Topic> select => fsql.Select<Topic>();
```
## 分组聚合

@@ -12,14 +12,12 @@ class Topic {
public string Title { get; set; }
public DateTime CreateTime { get; set; }
}
ISelect<Topic> select => fsql.Select<Topic>();
```
## 每页20条数据查询第1页
```csharp
var sql = select.Page(1, 20).ToSql();
var sql = fsql.Select<Topic>().Page(1, 20).ToSql();
///SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime`
//FROM `tb_topic` a
//LIMIT 0,20

@@ -12,23 +12,27 @@ class Topic {
public string Title { get; set; }
public DateTime CreateTime { get; set; }
}
ISelect<Topic> select => fsql.Select<Topic>();
```
## 单表
```csharp
var sql = select.Where(a => a.Id == 10).ToSql();
var sql = fsql.Select<Topic>()
.Where(a => a.Id == 10)
.ToSql();
///SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime`
//FROM `tb_topic` a
//WHERE (a.`Id` = 10)
sql = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100).ToSql();
sql = fsql.Select<Topic>()
.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100)
.ToSql();
///SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime`
//FROM `tb_topic` a
//WHERE (a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100)
sql = select.Where(a => new []{1,2,3}.Contains(a.Id)).ToSql();
sql = fsql.Select<Topic>()
.Where(a => new []{1,2,3}.Contains(a.Id))
.ToSql();
//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime`
//FROM `tb_topic` a
//WHERE (a.`Id` in (1,2,3))
@@ -38,7 +42,8 @@ sql = select.Where(a => new []{1,2,3}.Contains(a.Id)).ToSql();
```csharp
var sql = fsql.Select<User>()
.AsTable((a, b) => "(select * from user where clicks > 10)")
.Page(1, 10).ToList()
.Page(1, 10)
.ToList()
```
> v1.0.1 ISelect 增加 WithSql("select * from user ...") 功能快速代理此方法

@@ -24,15 +24,14 @@ class TestTypeParentInfo {
public int Id { get; set; }
public string Name { get; set; }
}
ISelect<Topic> select => fsql.Select<Topic>();
```
## 1、导航属性联表
```csharp
sql = select
sql = fsql.Select<Topic>()
.LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid)
.LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).ToSql();
.LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId)
.ToSql();
//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime`
//FROM `tb_topic` a
//LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid`
@@ -43,7 +42,9 @@ sql = select
## 2、普通联表
```csharp
sql = select.LeftJoin<TestTypeInfo>((a, b) => b.Guid == a.TestTypeInfoGuid).ToSql();
sql = fsql.Select<Topic>()
.LeftJoin<TestTypeInfo>((a, b) => b.Guid == a.TestTypeInfoGuid)
.ToSql();
//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime`
//FROM `tb_topic` a
//LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid`
@@ -51,14 +52,16 @@ sql = select.LeftJoin<TestTypeInfo>((a, b) => b.Guid == a.TestTypeInfoGuid).ToSq
## 3、复杂联表
```csharp
sql = select.From<TestTypeInfo, TestTypeParentInfo>((s, b, c) => s
sql = fsql.Select<Topic>().From<TestTypeInfo, TestTypeParentInfo>((s, b, c) => s
.LeftJoin(a => a.TestTypeInfoGuid == b.Guid)
.LeftJoin(a => b.ParentId == c.Id)).ToSql();
.LeftJoin(a => b.ParentId == c.Id))
.ToSql();
//或者
sql = fsql.Select<Topic, TestTypeInfo, TestTypeParentInfo>()
.LeftJoin((a,b,c) => a.TestTypeInfoGuid == b.Guid)
.LeftJoin((a,b,c) => b.ParentId == c.id).ToSql();
.LeftJoin((a,b,c) => b.ParentId == c.id)
.ToSql();
//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime`
//FROM `tb_topic` a
//LEFT JOIN `TestTypeInfo` b ON a.`TestTypeInfoGuid` = b.`Guid`
@@ -67,7 +70,9 @@ sql = fsql.Select<Topic, TestTypeInfo, TestTypeParentInfo>()
## 4、SQL联表
```csharp
sql = select.LeftJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = ?bname", new { bname = "xxx" }).ToSql();
sql = fsql.Select<Topic>()
.LeftJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = ?bname", new { bname = "xxx" })
.ToSql();
//SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime`
//FROM `tb_topic` a
//LEFT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = ?bname
@@ -75,7 +80,9 @@ sql = select.LeftJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name
## 5、子表Exists
```csharp
var list2 = select.Where(a => select.As("b").Where(b => b.Id == a.Id).Any()).ToList();
var list2 = fsql.Select<Topic>()
.Where(a => fsql.Select<Topic>().As("b").Where(b => b.Id == a.Id).Any())
.ToList();
// SELECT a.`Id`, a.`TypeGuid`, a.`Title`, a.`CreateTime`
// FROM `xxx` a
// WHERE (exists(SELECT 1
@@ -88,7 +95,9 @@ var list2 = select.Where(a => select.As("b").Where(b => b.Id == a.Id).Any()).ToL
## 6、子表In
```csharp
var list2 = select.Where(a => select.As("b").ToList(b => b.Id).Contains(a.Id)).ToList();
var list2 = fsql.Select<Topic>()
.Where(a => fsql.Select<Topic>().As("b").ToList(b => b.Id).Contains(a.Id))
.ToList();
// SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime`
// FROM `tb_topic` a
// WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title`
@@ -97,7 +106,8 @@ var list2 = select.Where(a => select.As("b").ToList(b => b.Id).Contains(a.Id)).T
## 7、子表First/Count/Sum/Max/Min/Avg
```csharp
var subquery = select.ToSql(a => new {
var subquery = fsql.Select<Topic>().ToSql(a => new
{
all = a,
first = fsql.Select<Child>().Where(b => b.ParentId == a.Id).First(b => b.Id),
count = fsql.Select<Child>().Where(b => b.ParentId == a.Id).Count(),

@@ -27,7 +27,7 @@ public class OrderDetail {
> 延时加载功能,依赖 FreeSql.Extensions.LazyLoading 包,请前往 nuget 下载;
```csharp
IFreeSql fsql = new FreeSql.FreeSqlBuilder()
static 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")
.UseLazyLoading(true) //开启延时加载功能
.UseMonitorCommand(

@@ -41,7 +41,7 @@ LEFT JOIN t2 on ... AND (t2.IsDeleted = 0)
WHERE t1.IsDeleted = 0
```
其中的实体可附加表达式时才生效,支持子表查询。单次查询使用的表数目越多收益越大。
实体可附加表达式时才生效,支持子表查询。单次查询使用的表数目越多收益越大。
可应用范围:

@@ -22,6 +22,8 @@ class ModelAopConfigEntity {
}
```
> v1.1 增加扩展包 [FreeSql.Extensions.EfCoreFluentApi](https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.EfCoreFluentApi),方便 EfCore 使用者过渡,使用方法接近 EfCore
## 优先级
数据库特性 > 实体特性 > FluentApi配置特性 > Aop配置特性

@@ -90,7 +90,7 @@ public static class DbFunc
{
var up = context.Value;
if (up.DataType == FreeSql.DataType.Sqlite) //重写内容
context.Value.Result = $"date_format({up.ParsedContent["that"]}, {up.ParsedContent["arg1"]})";
up.Result = $"date_format({up.ParsedContent["that"]}, {up.ParsedContent["arg1"]})";
return that;
}
}

@@ -23,8 +23,9 @@ static IFreeSql fsql = new FreeSql.FreeSqlBuilder()
.UseSlave("connectionString1", "connectionString2") //使用从数据库,支持多个
.Build(); //请务必定义成 Singleton 单例模式
select.Where(a => a.Id == 1).ToOne(); //读【从库】(默认)
select.Master().WhereId(a => a.Id == 1).ToOne(); //强制读【主库】
fsql.Select<T>().Where(a => a.Id == 1).ToOne(); //读【从库】(默认)
fsql.Select<T>().Master().WhereId(a => a.Id == 1).ToOne(); //强制读【主库】
```
## 参考资料

@@ -173,7 +173,7 @@ LEFT JOIN t2 on ... AND (t2.IsDeleted = 0)
WHERE t1.IsDeleted = 0
```
其中的实体可附加表达式时才生效,支持子表查询。单次查询使用的表数目越多收益越大。
实体可附加表达式时才生效,支持子表查询。单次查询使用的表数目越多收益越大。
---
@@ -256,42 +256,15 @@ public static class DbFunc
{
var up = context.Value;
if (up.DataType == FreeSql.DataType.Sqlite) //重写内容
context.Value.Result = $"date_format({up.ParsedContent["that"]}, {up.ParsedContent["arg1"]})";
up.Result = $"date_format({up.ParsedContent["that"]}, {up.ParsedContent["arg1"]})";
return that;
}
public static string SetDbParameter(this string that, int size)
{
if (context.Value.DbParameter != null)
{
//已经参数化了,直接修改长度
//提示:此条件可能开启了全局表达式参数化功能 UseGenerateCommandParameterWithLambda(true)
context.Value.DbParameter.Size = size;
return that;
}
var guid = Guid.NewGuid().ToString("N").ToLower();
context.Value.UserParameters.Add(new SqlParameter
{
ParameterName = guid,
SqlDbType = System.Data.SqlDbType.VarChar,
Size = size,
Value = that
});
return $"@{guid}"; //重写内容
}
}
var sql1 = fsql.Select<SysModule>()
.ToSql(a => a.CreateTime.FormatDateTime("yyyy-MM-dd"));
//SELECT date_format(a."CreateTime", 'yyyy-MM-dd') as1
//FROM "SysModule" a
var sql2 = fsql.Select<SysModule>()
.Where(a => a.Title == "123123".SetDbParameter(20))
.ToSql();
//SELECT ...
//FROM [SysModule] a
//WHERE (a.[Title] = @6a8b79d7001540369a2f52ecbba15679)
```
\[ExpressionCall\] 特性可在静态扩展类上标记,也可以在单个静态方法上标记;