initial commit

This commit is contained in:
tk
2024-11-13 18:18:28 +08:00
commit 013f35e296
1500 changed files with 443723 additions and 0 deletions

View File

@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "5.0.0",
"commands": [
"dotnet-ef"
]
}
}
}

View File

@ -0,0 +1,251 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using FreeSql;
using Microsoft.AspNetCore.Mvc;
namespace dbcontext_01.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly IFreeSql _orm;
private readonly SongContext _songContext;
private readonly CurdAfterLog _curdLog;
public ValuesController(SongContext songContext, IFreeSql orm1, CurdAfterLog curdLog)
{
_songContext = songContext;
_orm = orm1;
_curdLog = curdLog;
}
// GET api/values
[HttpGet]
public async Task<string> Get()
{
_orm.SetDbContextOptions(opt =>
{
opt.OnEntityChange = changeReport =>
{
Console.WriteLine(changeReport);
};
});
long id = 0;
try
{
var repos2Song = _orm.GetRepository<Song, int>();
repos2Song.Where(a => a.Id > 10).ToList();
//查询结果,进入 states
var song = new Song { Title = "empty" };
repos2Song.Insert(song);
song.Title = "empty01";
repos2Song.Update(song);
id = song.Id;
var adds = Enumerable.Range(0, 100)
.Select(a => new Song { CreateTime = DateTime.Now, Title = "xxxx" + a, Url = "url222" })
.ToList();
//创建一堆无主键值
repos2Song.Insert(adds);
for (var a = 0; a < 10; a++)
adds[a].Title = "dkdkdkdk" + a;
repos2Song.Update(adds);
//批量修改
repos2Song.Delete(adds.Skip(10).Take(20).ToList());
//批量删除10-20 元素的主键值会被清除
adds.Last().Url = "skldfjlksdjglkjjcccc";
repos2Song.Update(adds.Last());
adds.First().Url = "skldfjlksdjglkjjcccc";
repos2Song.Update(adds.First());
var ctx = _songContext;
var tag = new Tag
{
Name = "testaddsublist"
};
ctx.Tags.Add(tag);
ctx.UnitOfWork.GetOrBeginTransaction();
var tagAsync = new Tag
{
Name = "testaddsublist"
};
await ctx.Tags.AddAsync(tagAsync);
ctx.Songs.Select.Where(a => a.Id > 10).ToList();
//查询结果,进入 states
song = new Song { Title = "empty" };
//可插入的 song
ctx.Songs.Add(song);
id = song.Id;
//因有自增类型立即开启事务执行SQL返回自增值
adds = Enumerable.Range(0, 100)
.Select(a => new Song { CreateTime = DateTime.Now, Title = "xxxx" + a, Url = "url222" })
.ToList();
//创建一堆无主键值
ctx.Songs.AddRange(adds);
//立即执行,将自增值赋给 adds 所有元素,因为有自增类型,如果其他类型,指定传入主键值,不会立即执行
for (var a = 0; a < 10; a++)
adds[a].Title = "dkdkdkdk" + a;
ctx.Songs.UpdateRange(adds);
//批量修改,进入队列
ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList());
//批量删除,进入队列,完成时 10-20 元素的主键值会被清除
//ctx.Songs.Update(adds.First());
adds.Last().Url = "skldfjlksdjglkjjcccc";
ctx.Songs.Update(adds.Last());
adds.First().Url = "skldfjlksdjglkjjcccc";
ctx.Songs.Update(adds.First());
//单条修改 urls 的值,进入队列
//throw new Exception("回滚");
//ctx.Songs.Select.First();
//这里做一个查询,会立即打包【执行队列】,避免没有提交的数据,影响查询结果
ctx.SaveChanges();
//打包【执行队列】,提交事务
using (var uow = _orm.CreateUnitOfWork())
{
var reposSong = uow.GetRepository<Song, int>();
reposSong.Where(a => a.Id > 10).ToList();
//查询结果,进入 states
song = new Song { Title = "empty" };
reposSong.Insert(song);
id = song.Id;
adds = Enumerable.Range(0, 100)
.Select(a => new Song { CreateTime = DateTime.Now, Title = "xxxx" + a, Url = "url222" })
.ToList();
//创建一堆无主键值
reposSong.Insert(adds);
for (var a = 0; a < 10; a++)
adds[a].Title = "dkdkdkdk" + a;
reposSong.Update(adds);
//批量修改
reposSong.Delete(adds.Skip(10).Take(20).ToList());
//批量删除10-20 元素的主键值会被清除
adds.Last().Url = "skldfjlksdjglkjjcccc";
reposSong.Update(adds.Last());
adds.First().Url = "skldfjlksdjglkjjcccc";
reposSong.Update(adds.First());
uow.Commit();
}
using (ctx = new SongContext())
{
song = new Song { Title = "empty" };
await ctx.Songs.AddAsync(song);
id = song.Id;
adds = Enumerable.Range(0, 100)
.Select(a => new Song { CreateTime = DateTime.Now, Title = "xxxx" + a, Url = "url222" })
.ToList();
await ctx.Songs.AddRangeAsync(adds);
for (var a = 0; a < adds.Count; a++)
adds[a].Title = "dkdkdkdk" + a;
ctx.Songs.UpdateRange(adds);
ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList());
//ctx.Songs.Update(adds.First());
adds.Last().Url = "skldfjlksdjglkjjcccc";
ctx.Songs.Update(adds.Last());
//throw new Exception("回滚");
await ctx.SaveChangesAsync();
}
}
catch
{
var item = await _orm.Select<Song>().Where(a => a.Id == id).FirstAsync();
throw;
}
var item22 = await _orm.Select<Song>().Where(a => a.Id == id).FirstAsync();
var item33 = await _orm.Select<Song>().Where(a => a.Id > id).ToListAsync();
return item22.Id.ToString() + "\r\n\r\n" + _curdLog.Sb.ToString();
}
// GET api/values/5
[HttpGet("{id}")]
public ActionResult<object> Get(int id)
{
return _orm.Select<Song>().Where(a => a.Id == id).First();
}
[HttpGet("get{id}")]
public ActionResult<string> Get2(int id)
{
var item1 = _orm.Select<Song>().Where(a => a.Id == id).First();
var item2 = _orm.Select<Song>().Where(a => a.Id == id).First();
return _curdLog.Sb.ToString();
}
// POST api/values
[HttpPost]
public void Post([FromBody] string value)
{
}
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}

View File

@ -0,0 +1,113 @@
using FreeSql;
using FreeSql.DataAnnotations;
using System;
using System.Collections.Generic;
namespace dbcontext_01
{
public class SongContext : DbContext
{
public DbSet<Song> Songs { get; set; }
public DbSet<Tag> Tags { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder builder)
{
builder.UseFreeSql(Startup.Fsql);
//这里直接指定一个静态的 IFreeSql 对象即可,切勿重新 Build()
}
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 List<Song> Songs { get; set; }
}
public class Song
{
[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 TypeId { 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 int Tag_id { get; set; }
public Tag Tag { get; set; }
}
public class Tag
{
[Column(IsIdentity = true)]
public int Id { get; set; }
public string Name { get; set; }
public List<Song> Songs { get; set; }
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Threading.Tasks;
using FreeSql;
using FreeSql.DataAnnotations;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace dbcontext_01
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<DeleteExistingFiles>True</DeleteExistingFiles>
<ExcludeApp_Data>False</ExcludeApp_Data>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<PublishProvider>FileSystem</PublishProvider>
<PublishUrl>bin\Release\net5.0\publish\</PublishUrl>
<WebPublishMethod>FileSystem</WebPublishMethod>
<SiteUrlToLaunchAfterPublish />
<TargetFramework>net5.0</TargetFramework>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
<ProjectGuid>690f89e0-a721-423f-8f5d-d262f73235ea</ProjectGuid>
<SelfContained>true</SelfContained>
<PublishSingleFile>True</PublishSingleFile>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:53030/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"dbcontext_01": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:53031/"
}
}
}

View File

@ -0,0 +1,84 @@
using FreeSql;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
namespace dbcontext_01
{
public class Startup
{
public Startup(IConfiguration configuration, ILoggerFactory loggerFactory)
{
Configuration = configuration;
Fsql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document2.db;Pooling=true;Max Pool Size=10")
//.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=10")
//.UseConnectionString(DataType.MySql, "Data Source=192.168.164.10;Port=33061;User ID=root;Password=123456;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=5")
//.UseSlave("Data Source=192.168.164.10;Port=33062;User ID=root;Password=123456;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=5")
//.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10")
//.UseSyncStructureToUpper(true)
.UseAutoSyncStructure(true)
.UseLazyLoading(true)
.UseNoneCommandParameter(true)
.UseMonitorCommand(cmd => { }, (cmd, log) => Trace.WriteLine(log))
.Build();
Fsql.Aop.CurdAfter += (s, e) =>
{
Console.WriteLine(e.Identifier + ": " + e.EntityType.FullName + " " + e.ElapsedMilliseconds + "ms, " + e.Sql);
CurdAfterLog.Current.Value?.Sb.AppendLine($"{Thread.CurrentThread.ManagedThreadId}: {e.EntityType.FullName} {e.ElapsedMilliseconds}ms, {e.Sql}");
};
}
enum MySql { }
enum PgSql { }
public IConfiguration Configuration { get; }
public static IFreeSql Fsql { get; private set; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddSingleton<IFreeSql>(Fsql);
services.AddFreeDbContext<SongContext>(options => options.UseFreeSql(Fsql));
services.AddScoped<CurdAfterLog>();
}
public void Configure(IApplicationBuilder app)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Console.OutputEncoding = Encoding.GetEncoding("GB2312");
Console.InputEncoding = Encoding.GetEncoding("GB2312");
app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" });
app.UseDeveloperExceptionPage();
app.UseRouting();
app.UseEndpoints(a => a.MapControllers());
}
}
public class CurdAfterLog : IDisposable
{
public static AsyncLocal<CurdAfterLog> Current = new AsyncLocal<CurdAfterLog>();
public StringBuilder Sb { get; } = new StringBuilder();
public CurdAfterLog()
{
Current.Value = this;
}
public void Dispose()
{
Sb.Clear();
Current.Value = null;
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>dbcontext_01.xml</DocumentationFile>
<WarningLevel>3</WarningLevel>
<NoWarn>1701;1702;1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Extensions\FreeSql.Extensions.LazyLoading\FreeSql.Extensions.LazyLoading.csproj" />
<ProjectReference Include="..\..\FreeSql.DbContext\FreeSql.DbContext.csproj" />
<ProjectReference Include="..\..\Providers\FreeSql.Provider.MySqlConnector\FreeSql.Provider.MySqlConnector.csproj" />
<ProjectReference Include="..\..\Providers\FreeSql.Provider.Sqlite\FreeSql.Provider.Sqlite.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>dbcontext_01</name>
</assembly>
<members>
</members>
</doc>