mirror of
https://github.com/dotnetcore/FreeSql.git
synced 2026-02-27 02:30:58 +08:00
update
180
DbContext.md
180
DbContext.md
@@ -16,12 +16,12 @@ FreeSql.DbContext 实现类似 EFCore 使用习惯,跟踪对象状态,最终
|
|||||||
0、通用方法,为啥是0???
|
0、通用方法,为啥是0???
|
||||||
```
|
```
|
||||||
using (var ctx = fsql.CreateDbContext()) {
|
using (var ctx = fsql.CreateDbContext()) {
|
||||||
//var db1 = ctx.Set<Song>();
|
//var db1 = ctx.Set<Song>();
|
||||||
//var db2 = ctx.Set<Tag>();
|
//var db2 = ctx.Set<Tag>();
|
||||||
|
|
||||||
var item = new Song { };
|
var item = new Song { };
|
||||||
ctx.Add(item);
|
ctx.Add(item);
|
||||||
ctx.SaveChanges();
|
ctx.SaveChanges();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -32,44 +32,108 @@ using (var ctx = fsql.CreateDbContext()) {
|
|||||||
```csharp
|
```csharp
|
||||||
public class SongContext : DbContext {
|
public class SongContext : DbContext {
|
||||||
|
|
||||||
public DbSet<Song> Songs { get; set; }
|
public DbSet<Song> Songs { get; set; }
|
||||||
public DbSet<Song> Tags { get; set; }
|
public DbSet<Tag> Tags { get; set; }
|
||||||
|
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder builder) {
|
protected override void OnConfiguring(DbContextOptionsBuilder builder) {
|
||||||
builder.UseFreeSql(dbcontext_01.Startup.Fsql);
|
builder.UseFreeSql(GlobalVar.fsql);
|
||||||
}
|
//这里直接指定一个静态的 IFreeSql 对象即可,切勿重新 Build()
|
||||||
|
}
|
||||||
|
|
||||||
|
//每个 DbContext 只触发一次
|
||||||
|
protected override void OnModelCreating(ICodeFirst codefirst)
|
||||||
|
{
|
||||||
|
codefirst.Entity<Song>(eb =>
|
||||||
|
{
|
||||||
|
eb.ToTable("tb_song");
|
||||||
|
eb.Ignore(a => a.Field1);
|
||||||
|
eb.Property(a => a.Title).HasColumnType("varchar(50)").IsRequired();
|
||||||
|
eb.Property(a => a.Url).HasMaxLength(100);
|
||||||
|
|
||||||
|
eb.Property(a => a.RowVersion).IsRowVersion();
|
||||||
|
eb.Property(a => a.CreateTime).HasDefaultValueSql("current_timestamp");
|
||||||
|
|
||||||
|
eb.HasKey(a => a.Id);
|
||||||
|
eb.HasIndex(a => new { a.Id, a.Title }).IsUnique().HasName("idx_xxx11");
|
||||||
|
|
||||||
|
//一对多、多对一
|
||||||
|
eb.HasOne(a => a.Type).HasForeignKey(a => a.TypeId).WithMany(a => a.Songs);
|
||||||
|
|
||||||
|
//多对多
|
||||||
|
eb.HasMany(a => a.Tags).WithMany(a => a.Songs, typeof(Song_tag));
|
||||||
|
});
|
||||||
|
|
||||||
|
codefirst.Entity<SongType>(eb =>
|
||||||
|
{
|
||||||
|
eb.HasMany(a => a.Songs).WithOne(a => a.Type).HasForeignKey(a => a.TypeId);
|
||||||
|
|
||||||
|
eb.HasData(new[]
|
||||||
|
{
|
||||||
|
new SongType
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Name = "流行",
|
||||||
|
Songs = new List<Song>(new[]
|
||||||
|
{
|
||||||
|
new Song{ Title = "真的爱你" },
|
||||||
|
new Song{ Title = "爱你一万年" },
|
||||||
|
})
|
||||||
|
},
|
||||||
|
new SongType
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Name = "乡村",
|
||||||
|
Songs = new List<Song>(new[]
|
||||||
|
{
|
||||||
|
new Song{ Title = "乡里乡亲" },
|
||||||
|
})
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
codefirst.SyncStructure<SongType>();
|
||||||
|
codefirst.SyncStructure<Song>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SongType
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
public class Song {
|
public List<Song> Songs { get; set; }
|
||||||
[Column(IsIdentity = true)]
|
|
||||||
public int Id { get; set; }
|
|
||||||
public DateTime? Create_time { get; set; }
|
|
||||||
public bool? Is_deleted { get; set; }
|
|
||||||
public string Title { get; set; }
|
|
||||||
public string Url { get; set; }
|
|
||||||
|
|
||||||
public virtual ICollection<Tag> Tags { get; set; }
|
|
||||||
}
|
}
|
||||||
public class Song_tag {
|
public class Song
|
||||||
public int Song_id { get; set; }
|
{
|
||||||
public virtual Song Song { get; set; }
|
[Column(IsIdentity = true)]
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Url { get; set; }
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
public int Tag_id { get; set; }
|
public int TypeId { get; set; }
|
||||||
public virtual Tag Tag { get; set; }
|
public SongType Type { get; set; }
|
||||||
|
public List<Tag> Tags { get; set; }
|
||||||
|
|
||||||
|
public int Field1 { get; set; }
|
||||||
|
public long RowVersion { get; set; }
|
||||||
}
|
}
|
||||||
|
public class Song_tag
|
||||||
|
{
|
||||||
|
public int Song_id { get; set; }
|
||||||
|
public Song Song { get; set; }
|
||||||
|
|
||||||
public class Tag {
|
public int Tag_id { get; set; }
|
||||||
[Column(IsIdentity = true)]
|
public Tag Tag { get; set; }
|
||||||
public int Id { get; set; }
|
}
|
||||||
public int? Parent_id { get; set; }
|
public class Tag
|
||||||
public virtual Tag Parent { get; set; }
|
{
|
||||||
|
[Column(IsIdentity = true)]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
public decimal? Ddd { get; set; }
|
public string Name { get; set; }
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
public virtual ICollection<Song> Songs { get; set; }
|
public List<Song> Songs { get; set; }
|
||||||
public virtual ICollection<Tag> Tags { get; set; }
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -80,30 +144,30 @@ long id = 0;
|
|||||||
|
|
||||||
using (var ctx = new SongContext()) {
|
using (var ctx = new SongContext()) {
|
||||||
|
|
||||||
var song = new Song { };
|
var song = new Song { };
|
||||||
await ctx.Songs.AddAsync(song);
|
await ctx.Songs.AddAsync(song);
|
||||||
id = song.Id;
|
id = song.Id;
|
||||||
|
|
||||||
var adds = Enumerable.Range(0, 100)
|
var adds = Enumerable.Range(0, 100)
|
||||||
.Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" })
|
.Select(a => new Song { Create_time = DateTime.Now, Is_deleted = false, Title = "xxxx" + a, Url = "url222" })
|
||||||
.ToList();
|
.ToList();
|
||||||
await ctx.Songs.AddRangeAsync(adds);
|
await ctx.Songs.AddRangeAsync(adds);
|
||||||
|
|
||||||
for (var a = 0; a < adds.Count; a++)
|
for (var a = 0; a < adds.Count; a++)
|
||||||
adds[a].Title = "dkdkdkdk" + a;
|
adds[a].Title = "dkdkdkdk" + a;
|
||||||
|
|
||||||
ctx.Songs.UpdateRange(adds);
|
ctx.Songs.UpdateRange(adds);
|
||||||
|
|
||||||
ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList());
|
ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList());
|
||||||
|
|
||||||
//ctx.Songs.Update(adds.First());
|
//ctx.Songs.Update(adds.First());
|
||||||
|
|
||||||
adds.Last().Url = "skldfjlksdjglkjjcccc";
|
adds.Last().Url = "skldfjlksdjglkjjcccc";
|
||||||
ctx.Songs.Update(adds.Last());
|
ctx.Songs.Update(adds.Last());
|
||||||
|
|
||||||
//throw new Exception("回滚");
|
//throw new Exception("回滚");
|
||||||
|
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -112,8 +176,8 @@ using (var ctx = new SongContext()) {
|
|||||||
```csharp
|
```csharp
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddSingleton<IFreeSql>(Fsql);
|
services.AddSingleton<IFreeSql>(Fsql);
|
||||||
services.AddFreeDbContext<SongContext>(options => options.UseFreeSql(Fsql));
|
services.AddFreeDbContext<SongContext>(options => options.UseFreeSql(Fsql));
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -175,9 +239,9 @@ Guid Id 的情况下,执行三次命令:前两次插入合并执行,update
|
|||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
fsql.SetDbContextOptions(opt => {
|
fsql.SetDbContextOptions(opt => {
|
||||||
opt.OnEntityChange = report => {
|
opt.OnEntityChange = report => {
|
||||||
Console.WriteLine(report);
|
Console.WriteLine(report);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -186,12 +250,12 @@ fsql.SetDbContextOptions(opt => {
|
|||||||
```csharp
|
```csharp
|
||||||
var ctx = fsql.CreateDbContext();
|
var ctx = fsql.CreateDbContext();
|
||||||
ctx.Options.OnEntityChange = report => {
|
ctx.Options.OnEntityChange = report => {
|
||||||
Console.WriteLine(report);
|
Console.WriteLine(report);
|
||||||
};
|
};
|
||||||
|
|
||||||
var uow = fsql.CreateUnitOfWork();
|
var uow = fsql.CreateUnitOfWork();
|
||||||
uow.OnEntityChange = report => {
|
uow.OnEntityChange = report => {
|
||||||
Console.WriteLine(report);
|
Console.WriteLine(report);
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -200,8 +264,8 @@ uow.OnEntityChange = report => {
|
|||||||
```csharp
|
```csharp
|
||||||
public class EntityChangeInfo
|
public class EntityChangeInfo
|
||||||
{
|
{
|
||||||
public object Object { get; set; }
|
public object Object { get; set; }
|
||||||
public EntityChangeType Type { get; set; }
|
public EntityChangeType Type { get; set; }
|
||||||
}
|
}
|
||||||
public enum EntityChangeType { Insert, Update, Delete, SqlRaw }
|
public enum EntityChangeType { Insert, Update, Delete, SqlRaw }
|
||||||
```
|
```
|
||||||
|
|||||||
37
FluentApi.md
37
FluentApi.md
@@ -2,12 +2,14 @@ FreeSql 提供使用 Fluent Api, 在外部配置实体的数据库特性,Flu
|
|||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
fsql.CodeFirst
|
fsql.CodeFirst
|
||||||
.ConfigEntity<TestFluenttb1>(a => {
|
.ConfigEntity<TestFluenttb1>(a =>
|
||||||
|
{
|
||||||
a.Name("xxdkdkdk1");
|
a.Name("xxdkdkdk1");
|
||||||
a.Property(b => b.Id).Name("Id22").IsIdentity(true);
|
a.Property(b => b.Id).Name("Id22").IsIdentity(true);
|
||||||
a.Property(b => b.name).DbType("varchar(100)").IsNullable(true);
|
a.Property(b => b.name).DbType("varchar(100)").IsNullable(true);
|
||||||
})
|
})
|
||||||
.ConfigEntity<TestFluenttb2>(a => {
|
.ConfigEntity<TestFluenttb2>(a =>
|
||||||
|
{
|
||||||
a.Name("xxdkdkdk2");
|
a.Name("xxdkdkdk2");
|
||||||
a.Property(b => b.Id).Name("Id22").IsIdentity(true);
|
a.Property(b => b.Id).Name("Id22").IsIdentity(true);
|
||||||
a.Property(b => b.name).DbType("varchar(100)").IsNullable(true);
|
a.Property(b => b.name).DbType("varchar(100)").IsNullable(true);
|
||||||
@@ -34,7 +36,36 @@ class TestFluenttb2
|
|||||||
|
|
||||||
参考:[《实体特性说明》](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
|
> FreeSql.DbContext v1.4.0+ 实现了 EfCore FluentApi 99% 相似的语法
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
fsql.CodeFirst.Entity<SongType>(eb =>
|
||||||
|
{
|
||||||
|
eb.HasMany(a => a.Songs).WithOne(a => a.Type).HasForeignKey(a => a.TypeId);
|
||||||
|
eb.HasData(new[]
|
||||||
|
{
|
||||||
|
new SongType
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Name = "流行",
|
||||||
|
Songs = new List<Song>(new[]
|
||||||
|
{
|
||||||
|
new Song{ Title = "真的爱你" },
|
||||||
|
new Song{ Title = "爱你一万年" },
|
||||||
|
})
|
||||||
|
},
|
||||||
|
new SongType
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Name = "乡村",
|
||||||
|
Songs = new List<Song>(new[]
|
||||||
|
{
|
||||||
|
new Song{ Title = "乡里乡亲" },
|
||||||
|
})
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
## 优先级
|
## 优先级
|
||||||
|
|
||||||
|
|||||||
2
更新日志.md
2
更新日志.md
@@ -4,6 +4,8 @@
|
|||||||
## v1.4.0-preview
|
## v1.4.0-preview
|
||||||
|
|
||||||
- 增加 FreeSql.Provider.Dameng 基于 DmProvider Ado.net 访问达梦数据库;
|
- 增加 FreeSql.Provider.Dameng 基于 DmProvider Ado.net 访问达梦数据库;
|
||||||
|
- 增加 FreeSql.DbContext OnModelCreating 虚方法,实现在 DbContext 使用 FluentApi;
|
||||||
|
- 移除 FreeSql.Extensions.EfCoreFluentApi,功能移至 FreeSql.DbContext;
|
||||||
- 增加 IInsert InsertColumns/IgnoreColumns 方法重载输入 string[];#275
|
- 增加 IInsert InsertColumns/IgnoreColumns 方法重载输入 string[];#275
|
||||||
- 增加 DbFirst 获取字段的默认值信息;
|
- 增加 DbFirst 获取字段的默认值信息;
|
||||||
- 增加 FreeSql.Generator -Match 参数只生成匹配的表;
|
- 增加 FreeSql.Generator -Match 参数只生成匹配的表;
|
||||||
|
|||||||
2
自定义特性.md
2
自定义特性.md
@@ -22,8 +22,6 @@ class ModelAopConfigEntity {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> v1.1 增加扩展包 [FreeSql.Extensions.EfCoreFluentApi](https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.EfCoreFluentApi),方便 EfCore 使用者过渡,使用方法接近 EfCore
|
|
||||||
|
|
||||||
## 优先级
|
## 优先级
|
||||||
|
|
||||||
数据库特性 > 实体特性 > FluentApi(配置特性) > Aop(配置特性)
|
数据库特性 > 实体特性 > FluentApi(配置特性) > Aop(配置特性)
|
||||||
|
|||||||
2
骚操作.md
2
骚操作.md
@@ -308,8 +308,6 @@ class ModelAopConfigEntity {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> [FluentApi 与 EfCore 90% 相似的扩展包](https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.EfCoreFluentApi)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# 13、审计 CURD
|
# 13、审计 CURD
|
||||||
|
|||||||
Reference in New Issue
Block a user