Skip to content

Commit e2d33e9

Browse files
2881028810
authored andcommitted
- 修复 ISelect.ToList(true) 无效的 bug;
- 增加 IAop.ConfigEntity 配置实体特性,可实现使用其他 ORM 的实体特性,#36
1 parent b16218d commit e2d33e9

File tree

10 files changed

+164
-36
lines changed

10 files changed

+164
-36
lines changed

FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using FreeSql.DataAnnotations;
2-
using FreeSql.Tests.DataContext.SqlServer;
32
using System;
3+
using System.Linq;
44
using Xunit;
55

66
namespace FreeSql.Tests.DataAnnotations {
@@ -9,6 +9,31 @@ public class MySqlFluentTest {
99
public MySqlFluentTest() {
1010
}
1111

12+
[Fact]
13+
public void AopConfigEntity() {
14+
g.mysql.CodeFirst.ConfigEntity<ModelAopConfigEntity>(a => a.Property(b => b.pkid).IsPrimary(true));
15+
16+
g.mysql.Aop.ConfigEntity = (s, e) => {
17+
var attr = e.EntityType.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.Schema.TableAttribute), false).FirstOrDefault() as System.ComponentModel.DataAnnotations.Schema.TableAttribute;
18+
if (attr != null) {
19+
e.ModifyResult.Name = attr.Name;
20+
}
21+
};
22+
g.mysql.Aop.ConfigEntityProperty = (s, e) => {
23+
if (e.Property.GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.KeyAttribute), false).Any()) {
24+
e.ModifyResult.IsPrimary = true;
25+
}
26+
};
27+
28+
var tsql1 = g.mysql.Select<ModelAopConfigEntity>().WhereDynamic(1).ToSql();
29+
}
30+
[System.ComponentModel.DataAnnotations.Schema.Table("xxx")]
31+
class ModelAopConfigEntity {
32+
[System.ComponentModel.DataAnnotations.Key]
33+
[Column(IsPrimary = false)]
34+
public int pkid { get; set; }
35+
}
36+
1237
[Fact]
1338
public void Fluent() {
1439
g.mysql.CodeFirst

FreeSql.Tests/FreeSql.Tests.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10+
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.8" />
1011
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
1112
<PackageReference Include="xunit" Version="2.4.0" />
1213
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
13-
<PackageReference Include="FreeSql.DbContext" Version="0.5.3" />
14+
<PackageReference Include="FreeSql.DbContext" Version="0.5.4" />
1415
</ItemGroup>
1516

1617
<ItemGroup>

FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ public void As() {
677677
[Fact]
678678
public void AsTable() {
679679

680-
var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList();
680+
var listt = select.AsTable((a, b) => "(select * from tb_topic22 where clicks > 10)").Page(1, 10).ToList();
681681

682682
Func<Type, string, string> tableRule = (type, oldname) => {
683683
if (type == typeof(Topic)) return oldname + "AsTable1";

FreeSql.Tests/UnitTest1.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,23 @@ public void Test1() {
153153
);
154154

155155

156+
var neworder = new Order {
157+
CustomerName = "testCustomer",
158+
OrderTitle = "xxx#cccksksk",
159+
TransactionDate = DateTime.Now,
160+
OrderDetails = new List<OrderDetail>(new[] {
161+
new OrderDetail {
156162

157-
var order = g.mysql.Select<Order>().Where(a => a.Id == 1).ToOne(); //查询订单表
163+
},
164+
new OrderDetail {
165+
166+
}
167+
})
168+
};
169+
170+
g.mysql.GetRepository<Order>().Insert(neworder);
171+
172+
var order = g.mysql.Select<Order>().Where(a => a.Id == neworder.Id).ToOne(); //查询订单表
158173
if (order == null) {
159174
var orderId = g.mysql.Insert(new Order { }).ExecuteIdentity();
160175
order = g.mysql.Select<Order>(orderId).ToOne();

FreeSql/DataAnnotations/TableAttribute.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@ public class TableAttribute : Attribute {
1616
/// 查询过滤SQL,实现类似 a.IsDeleted = 1 功能
1717
/// </summary>
1818
public string SelectFilter { get; set; }
19-
20-
internal bool? _RowVersion;
21-
/// <summary>
22-
/// 修改/删除时,启用行版本检查
23-
/// </summary>
24-
public bool RowVersion { get => _RowVersion ?? false; set => _RowVersion = value; }
2519

2620
internal ConcurrentDictionary<string, ColumnAttribute> _columns { get; } = new ConcurrentDictionary<string, ColumnAttribute>(StringComparer.CurrentCultureIgnoreCase);
2721
}

FreeSql/FreeSql.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFramework>netstandard2.0</TargetFramework>
5-
<Version>0.5.3</Version>
5+
<Version>0.5.4</Version>
66
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
77
<Authors>YeXiangQin</Authors>
88
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>

FreeSql/Interface/IAop.cs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
using FreeSql.DatabaseModel;
1+
using FreeSql.DataAnnotations;
2+
using FreeSql.DatabaseModel;
23
using System;
34
using System.Collections.Generic;
45
using System.Linq.Expressions;
6+
using System.Reflection;
57

68
namespace FreeSql {
79
public interface IAop {
@@ -20,6 +22,15 @@ public interface IAop {
2022
/// 可自定义解析表达式
2123
/// </summary>
2224
EventHandler<AopParseExpressionEventArgs> ParseExpression { get; set; }
25+
26+
/// <summary>
27+
/// 自定义实体的配置,方便和多个 ORM 共同使用
28+
/// </summary>
29+
EventHandler<AopConfigEntityEventArgs> ConfigEntity { get; set; }
30+
/// <summary>
31+
/// 自定义实体的属性配置,方便和多个 ORM 共同使用
32+
/// </summary>
33+
EventHandler<AopConfigEntityPropertyEventArgs> ConfigEntityProperty { get; set; }
2334
}
2435

2536
public class AopToListEventArgs : EventArgs {
@@ -61,4 +72,39 @@ public AopParseExpressionEventArgs(Expression expression, Func<Expression, strin
6172
/// </summary>
6273
public string Result { get; set; }
6374
}
75+
public class AopConfigEntityEventArgs : EventArgs {
76+
public AopConfigEntityEventArgs(Type entityType) {
77+
this.EntityType = entityType;
78+
this.ModifyResult = new TableAttribute();
79+
}
80+
81+
/// <summary>
82+
/// 实体类型
83+
/// </summary>
84+
public Type EntityType { get; }
85+
/// <summary>
86+
/// 实体配置
87+
/// </summary>
88+
public TableAttribute ModifyResult { get; }
89+
}
90+
public class AopConfigEntityPropertyEventArgs : EventArgs {
91+
public AopConfigEntityPropertyEventArgs(Type entityType, PropertyInfo property) {
92+
this.EntityType = entityType;
93+
this.Property = property;
94+
this.ModifyResult = new ColumnAttribute();
95+
}
96+
97+
/// <summary>
98+
/// 实体类型
99+
/// </summary>
100+
public Type EntityType { get; }
101+
/// <summary>
102+
/// 实体的属性
103+
/// </summary>
104+
public PropertyInfo Property { get; }
105+
/// <summary>
106+
/// 实体的属性配置
107+
/// </summary>
108+
public ColumnAttribute ModifyResult { get; }
109+
}
64110
}

FreeSql/Internal/CommonProvider/AopProvider.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@ class AopProvider : IAop {
99
public EventHandler<AopToListEventArgs> ToList { get; set; }
1010
public EventHandler<AopWhereEventArgs> Where { get; set; }
1111
public EventHandler<AopParseExpressionEventArgs> ParseExpression { get; set; }
12+
public EventHandler<AopConfigEntityEventArgs> ConfigEntity { get; set; }
13+
public EventHandler<AopConfigEntityPropertyEventArgs> ConfigEntityProperty { get; set; }
1214
}
1315
}

FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,10 @@ await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => {
288288
return ret;
289289
});
290290
}
291-
public List<T1> ToList(bool includeNestedMembers = false) => this.ToListPrivate(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevel2());
292-
public Task<List<T1>> ToListAsync(bool includeNestedMembers = false) => this.ToListPrivateAsync(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevel2());
291+
public List<T1> ToList(bool includeNestedMembers = false) =>
292+
this.ToListPrivate(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll());
293+
public Task<List<T1>> ToListAsync(bool includeNestedMembers = false) =>
294+
this.ToListPrivateAsync(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll());
293295
public T1 ToOne() {
294296
this.Limit(1);
295297
return this.ToList().FirstOrDefault();
@@ -350,7 +352,7 @@ public class GetAllFieldExpressionTreeInfo {
350352
public Func<IFreeSql, DbDataReader, T1> Read { get; set; }
351353
}
352354
protected GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevelAll() {
353-
return _dicGetAllFieldExpressionTree.GetOrAdd(string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Alias}-{a.Type}")), s => {
355+
return _dicGetAllFieldExpressionTree.GetOrAdd($"*{string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Alias}-{a.Type}"))}", s => {
354356
var type = _tables.First().Table.TypeLazy ?? _tables.First().Table.Type;
355357
var ormExp = Expression.Parameter(typeof(IFreeSql), "orm");
356358
var rowExp = Expression.Parameter(typeof(DbDataReader), "row");

FreeSql/Internal/CommonUtils.cs

Lines changed: 64 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -58,31 +58,74 @@ internal TableAttribute GetConfigEntity(Type type) {
5858
return dicConfigEntity.TryGetValue(type, out var trytb) ? trytb : null;
5959
}
6060
internal TableAttribute GetEntityTableAttribute(Type type) {
61-
var attr = type.GetCustomAttributes(typeof(TableAttribute), false).LastOrDefault() as TableAttribute;
62-
if (dicConfigEntity.TryGetValue(type, out var trytb) == false) return attr;
61+
TableAttribute attr = null;
62+
if (_orm.Aop.ConfigEntity != null) {
63+
var aope = new AopConfigEntityEventArgs(type);
64+
_orm.Aop.ConfigEntity(_orm, aope);
65+
attr = aope.ModifyResult;
66+
}
6367
if (attr == null) attr = new TableAttribute();
64-
65-
if (string.IsNullOrEmpty(attr.Name)) attr.Name = trytb.Name;
66-
if (string.IsNullOrEmpty(attr.OldName)) attr.OldName = trytb.OldName;
67-
if (string.IsNullOrEmpty(attr.SelectFilter)) attr.SelectFilter = trytb.SelectFilter;
68-
return attr;
68+
if (dicConfigEntity.TryGetValue(type, out var trytb)) {
69+
if (!string.IsNullOrEmpty(trytb.Name)) attr.Name = trytb.Name;
70+
if (!string.IsNullOrEmpty(trytb.OldName)) attr.OldName = trytb.OldName;
71+
if (!string.IsNullOrEmpty(trytb.SelectFilter)) attr.SelectFilter = trytb.SelectFilter;
72+
}
73+
var attrs = type.GetCustomAttributes(typeof(TableAttribute), false);
74+
foreach (var tryattrobj in attrs) {
75+
var tryattr = tryattrobj as TableAttribute;
76+
if (tryattr == null) continue;
77+
if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name;
78+
if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName;
79+
if (!string.IsNullOrEmpty(tryattr.SelectFilter)) attr.SelectFilter = tryattr.SelectFilter;
80+
}
81+
if (!string.IsNullOrEmpty(attr.Name)) return attr;
82+
if (!string.IsNullOrEmpty(attr.OldName)) return attr;
83+
if (!string.IsNullOrEmpty(attr.SelectFilter)) return attr;
84+
return null;
6985
}
7086
internal ColumnAttribute GetEntityColumnAttribute(Type type, PropertyInfo proto) {
71-
var attr = proto.GetCustomAttributes(typeof(ColumnAttribute), false).LastOrDefault() as ColumnAttribute;
72-
if (dicConfigEntity.TryGetValue(type, out var trytb) == false) return attr;
73-
if (trytb._columns.TryGetValue(proto.Name, out var trycol) == false) return attr;
87+
ColumnAttribute attr = null;
88+
if (_orm.Aop.ConfigEntityProperty != null) {
89+
var aope = new AopConfigEntityPropertyEventArgs(type, proto);
90+
_orm.Aop.ConfigEntityProperty(_orm, aope);
91+
attr = aope.ModifyResult;
92+
}
7493
if (attr == null) attr = new ColumnAttribute();
75-
76-
if (string.IsNullOrEmpty(attr.Name)) attr.Name = trycol.Name;
77-
if (string.IsNullOrEmpty(attr.OldName)) attr.OldName = trycol.OldName;
78-
if (string.IsNullOrEmpty(attr.DbType)) attr.DbType = trycol.DbType;
79-
if (attr._IsPrimary == null) attr._IsPrimary = trycol.IsPrimary;
80-
if (attr._IsIdentity == null) attr._IsIdentity = trycol.IsIdentity;
81-
if (attr._IsNullable == null) attr._IsNullable = trycol.IsNullable;
82-
if (attr._IsIgnore == null) attr._IsIgnore = trycol.IsIgnore;
83-
if (attr._IsVersion == null) attr._IsVersion = trycol.IsVersion;
84-
if (attr.DbDefautValue == null) attr.DbDefautValue = trycol.DbDefautValue;
85-
return attr;
94+
if (dicConfigEntity.TryGetValue(type, out var trytb) && trytb._columns.TryGetValue(proto.Name, out var trycol)) {
95+
if (!string.IsNullOrEmpty(trycol.Name)) attr.Name = trycol.Name;
96+
if (!string.IsNullOrEmpty(trycol.OldName)) attr.OldName = trycol.OldName;
97+
if (!string.IsNullOrEmpty(trycol.DbType)) attr.DbType = trycol.DbType;
98+
if (trycol._IsPrimary != null) attr._IsPrimary = trycol.IsPrimary;
99+
if (trycol._IsIdentity != null) attr._IsIdentity = trycol.IsIdentity;
100+
if (trycol._IsNullable != null) attr._IsNullable = trycol.IsNullable;
101+
if (trycol._IsIgnore != null) attr._IsIgnore = trycol.IsIgnore;
102+
if (trycol._IsVersion != null) attr._IsVersion = trycol.IsVersion;
103+
if (trycol.DbDefautValue != null) attr.DbDefautValue = trycol.DbDefautValue;
104+
}
105+
var attrs = proto.GetCustomAttributes(typeof(ColumnAttribute), false);
106+
foreach (var tryattrobj in attrs) {
107+
var tryattr = tryattrobj as ColumnAttribute;
108+
if (tryattr == null) continue;
109+
if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name;
110+
if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName;
111+
if (!string.IsNullOrEmpty(tryattr.DbType)) attr.DbType = tryattr.DbType;
112+
if (tryattr._IsPrimary != null) attr._IsPrimary = tryattr.IsPrimary;
113+
if (tryattr._IsIdentity != null) attr._IsIdentity = tryattr.IsIdentity;
114+
if (tryattr._IsNullable != null) attr._IsNullable = tryattr.IsNullable;
115+
if (tryattr._IsIgnore != null) attr._IsIgnore = tryattr.IsIgnore;
116+
if (tryattr._IsVersion != null) attr._IsVersion = tryattr.IsVersion;
117+
if (tryattr.DbDefautValue != null) attr.DbDefautValue = tryattr.DbDefautValue;
118+
}
119+
if (!string.IsNullOrEmpty(attr.Name)) return attr;
120+
if (!string.IsNullOrEmpty(attr.OldName)) return attr;
121+
if (!string.IsNullOrEmpty(attr.DbType)) return attr;
122+
if (attr._IsPrimary != null) return attr;
123+
if (attr._IsIdentity != null) return attr;
124+
if (attr._IsNullable != null) return attr;
125+
if (attr._IsIgnore != null) return attr;
126+
if (attr._IsVersion != null) return attr;
127+
if (attr.DbDefautValue != null) return attr;
128+
return null;
86129
}
87130

88131
internal string WhereObject(TableInfo table, string aliasAndDot, object dywhere) {

0 commit comments

Comments
 (0)