Skip to content

Commit ca53986

Browse files
committed
[Add]工作单元开关,可在任意 Insert/Update/Delete 之前调用,以关闭工作单元使其失效
1 parent 7328b5e commit ca53986

File tree

3 files changed

+163
-6
lines changed

3 files changed

+163
-6
lines changed

FreeSql.DbContext.Tests/RepositoryTests.cs

Lines changed: 124 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public class AddUpdateInfo {
7575

7676
[Fact]
7777
public void UnitOfWorkRepository() {
78-
foreach (var fsql in new[] { g.sqlite, /*g.mysql,*/ g.pgsql, g.oracle, g.sqlserver }) {
78+
foreach (var fsql in new[] { g.sqlite, /*g.mysql, g.pgsql, g.oracle, g.sqlserver*/ }) {
7979

8080
fsql.CodeFirst.ConfigEntity<FlowModel>(f => {
8181
f.Property(b => b.UserId).IsPrimary(true);
@@ -104,9 +104,130 @@ public void UnitOfWorkRepository() {
104104
flowRepos.Insert(flow);
105105
uow.Commit();
106106
}
107-
}
107+
}
108108
}
109-
public partial class FlowModel {
109+
110+
[Fact]
111+
public void UnitOfWorkRepositoryWithDisableBeforeInsert()
112+
{
113+
foreach (var fsql in new[] { g.sqlite, })
114+
{
115+
fsql.CodeFirst.ConfigEntity<FlowModel>(f => {
116+
f.Property(b => b.UserId).IsPrimary(true);
117+
f.Property(b => b.Id).IsPrimary(true).IsIdentity(true);
118+
f.Property(b => b.Name).IsNullable(false);
119+
});
120+
121+
var flowRepos = fsql.GetRepository<FlowModel>();
122+
123+
var flow = new FlowModel()
124+
{
125+
CreateTime = DateTime.Now,
126+
Name = "aaa",
127+
LastModifyTime = DateTime.Now,
128+
UserId = 1,
129+
};
130+
131+
//清理掉数据库中已存在的数据,为了接下来的插入测试
132+
flowRepos.Delete(a => a.UserId == 1 &&a.Name== "aaa");
133+
134+
using (var uow = fsql.CreateUnitOfWork())
135+
{
136+
//关闭工作单元(不会开始事务)
137+
uow.Disable();
138+
var uowFlowRepos = uow.GetRepository<FlowModel>();
139+
uowFlowRepos.Insert(flow);
140+
//已关闭工作单元,提不提交都没影响,此处注释来确定工作单元开关是否生效:关闭了,不Commit也应该插入数据
141+
//uow.Commit();
142+
}
143+
144+
Assert.True(flowRepos.Select.Any(a => a.UserId == 1 && a.Name == "aaa"));
145+
}
146+
147+
}
148+
149+
[Fact]
150+
public void UnitOfWorkRepositoryWithDisableAfterInsert()
151+
{
152+
foreach (var fsql in new[] {g.sqlite,})
153+
{
154+
fsql.CodeFirst.ConfigEntity<FlowModel>(f =>
155+
{
156+
f.Property(b => b.UserId).IsPrimary(true);
157+
f.Property(b => b.Id).IsPrimary(true).IsIdentity(true);
158+
f.Property(b => b.Name).IsNullable(false);
159+
});
160+
161+
var flowRepos = fsql.GetRepository<FlowModel>();
162+
163+
//清理掉数据库中已存在的数据,为了接下来的插入测试
164+
flowRepos.Delete(a => a.UserId == 1 && a.Name == "aaa");
165+
166+
var flow = new FlowModel()
167+
{
168+
CreateTime = DateTime.Now,
169+
Name = "aaa",
170+
LastModifyTime = DateTime.Now,
171+
UserId = 1,
172+
};
173+
174+
175+
Assert.Throws<Exception>(() =>
176+
{
177+
using (var uow = fsql.CreateUnitOfWork())
178+
{
179+
var uowFlowRepos = uow.GetRepository<FlowModel>();
180+
uowFlowRepos.Insert(flow);
181+
//有了任意 Insert/Update/Delete 调用关闭uow的方法将会发生异常
182+
uow.Disable();
183+
uow.Commit();
184+
}
185+
186+
});
187+
}
188+
}
189+
190+
[Fact]
191+
public void UnitOfWorkRepositoryWithoutDisable()
192+
{
193+
foreach (var fsql in new[] { g.sqlite, })
194+
{
195+
fsql.CodeFirst.ConfigEntity<FlowModel>(f =>
196+
{
197+
f.Property(b => b.UserId).IsPrimary(true);
198+
f.Property(b => b.Id).IsPrimary(true).IsIdentity(true);
199+
f.Property(b => b.Name).IsNullable(false);
200+
});
201+
202+
var flowRepos = fsql.GetRepository<FlowModel>();
203+
if (flowRepos.Select.Any(a => a.UserId == 1 && a.Name == "aaa"))
204+
{
205+
flowRepos.Delete(a => a.UserId == 1);
206+
}
207+
208+
209+
var flow = new FlowModel()
210+
{
211+
CreateTime = DateTime.Now,
212+
Name = "aaa",
213+
LastModifyTime = DateTime.Now,
214+
UserId = 1,
215+
};
216+
217+
218+
using (var uow = fsql.CreateUnitOfWork())
219+
{
220+
var uowFlowRepos = uow.GetRepository<FlowModel>();
221+
uowFlowRepos.Insert(flow);
222+
//不调用commit将不会提交数据库更改
223+
//uow.Commit();
224+
}
225+
Assert.False(flowRepos.Select.Any(a => a.UserId == 1 && a.Name == "aaa"));
226+
}
227+
}
228+
229+
230+
public partial class FlowModel {
110231
public int UserId { get; set; }
111232
public int Id { get; set; }
112233
public int? ParentId { get; set; }

FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,21 @@ public interface IUnitOfWork : IDisposable {
1212

1313
IsolationLevel? IsolationLevel { get; set; }
1414

15-
void Commit();
15+
/// <summary>
16+
/// 是否启用工作单元
17+
/// </summary>
18+
bool Enable { get; }
19+
20+
void Commit();
1621

1722
void Rollback();
18-
}
23+
24+
/// <summary>
25+
/// 禁用工作单元
26+
/// <exception cref="Exception"></exception>
27+
/// <para></para>
28+
/// 若已开启事务(已有Insert/Update/Delete操作),调用此方法将发生异常,建议在执行逻辑前调用
29+
/// </summary>
30+
void Disable();
31+
}
1932
}

FreeSql.DbContext/UnitOfWork/UnitOfWork.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,35 @@ void ReturnObject() {
2323
_conn = null;
2424
}
2525

26-
public IsolationLevel? IsolationLevel { get; set; }
26+
27+
/// <summary>
28+
/// 是否启用工作单元
29+
/// </summary>
30+
public bool Enable { get; private set; } = true;
31+
32+
/// <summary>
33+
/// 禁用工作单元
34+
/// <exception cref="Exception"></exception>
35+
/// <para></para>
36+
/// 若已开启事务(已有Insert/Update/Delete操作),调用此方法将发生异常,建议在执行逻辑前调用
37+
/// </summary>
38+
public void Disable()
39+
{
40+
if (_tran != null)
41+
{
42+
throw new Exception("已开启事务,不能禁用工作单元");
43+
}
44+
45+
Enable = false;
46+
}
47+
48+
public IsolationLevel? IsolationLevel { get; set; }
2749

2850
public DbTransaction GetOrBeginTransaction(bool isCreate = true) {
2951

3052
if (_tran != null) return _tran;
3153
if (isCreate == false) return null;
54+
if (!Enable) return null;
3255
if (_conn != null) _fsql.Ado.MasterPool.Return(_conn);
3356

3457
_conn = _fsql.Ado.MasterPool.Get();

0 commit comments

Comments
 (0)