Skip to content

Commit f25fda4

Browse files
committed
✨ feat(domain): 增强实体框架功能
- 添加 EntityEquals 方法用于比较实体对象 - 实现 CreateKey 方法以支持不同类型 ID 的生成 - 增加多租户相关功能,如 IsMultiTenantEntity 和 AllowSameIdAcrossTenants - 优化 EntityHelper 类,提供更灵活的 ID 生成和实体比较功能
1 parent 97f214a commit f25fda4

File tree

2 files changed

+67
-7
lines changed

2 files changed

+67
-7
lines changed

framework/src/Bing.Ddd.Domain/Bing/Domain/Entities/EntityBase.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System.ComponentModel.DataAnnotations;
22
using Bing.Extensions;
3-
using Bing.Helpers;
43
using Bing.Properties;
54
using Bing.Validation;
65

@@ -31,14 +30,24 @@ public abstract class EntityBase : IEntity
3130
/// 输出字符串
3231
/// </summary>
3332
public override string ToString() => $"[Entity: {GetType().Name}] Keys = {GetKeys().Join(", ")}";
33+
34+
/// <summary>
35+
/// 确定当前实体是否等于另一个实体。
36+
/// </summary>
37+
/// <param name="other">要比较的实体对象。</param>
38+
/// <returns>
39+
/// 如果两个实体相等,则返回 <c>true</c>;否则返回 <c>false</c>。
40+
/// </returns>
41+
public bool EntityEquals(IEntity other) => EntityHelper.EntityEquals(this, other);
3442
}
3543

3644
/// <summary>
3745
/// 领域实体
3846
/// </summary>
3947
/// <typeparam name="TEntity">实体类型</typeparam>
4048
[Serializable]
41-
public abstract class EntityBase<TEntity> : EntityBase<TEntity, Guid> where TEntity : class, IEntity, IVerifyModel<TEntity>
49+
public abstract class EntityBase<TEntity> : EntityBase<TEntity, Guid>
50+
where TEntity : class, IEntity, IVerifyModel<TEntity>
4251
{
4352
/// <summary>
4453
/// 初始化一个<see cref="EntityBase{TEntity}"/>类型的实例
@@ -129,6 +138,7 @@ protected EntityBase() { }
129138
/// </summary>
130139
protected virtual void InitId()
131140
{
141+
// TODO: 考虑跳过该判断方法
132142
if (typeof(TKey) == typeof(int) || typeof(TKey) == typeof(long))
133143
return;
134144
if (string.IsNullOrWhiteSpace(Id.SafeString()) || Id.Equals(default(TKey)))
@@ -138,7 +148,7 @@ protected virtual void InitId()
138148
/// <summary>
139149
/// 创建标识
140150
/// </summary>
141-
protected virtual TKey CreateId() => Conv.To<TKey>(EntityHelper.GuidGenerateFunc());
151+
protected virtual TKey CreateId() => EntityHelper.CreateKey<TKey>();
142152

143153
/// <summary>
144154
/// 验证

framework/src/Bing.Ddd.Domain/Bing/Domain/Entities/EntityHelper.cs

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,58 @@ namespace Bing.Domain.Entities;
1212
public static class EntityHelper
1313
{
1414
/// <summary>
15-
/// Guid 生成函数
15+
/// ID生成器字典
16+
/// </summary>
17+
private static readonly IDictionary<Type, Func<object>> _idGenerators = new Dictionary<Type, Func<object>>
18+
{
19+
{ typeof(Guid), () => GuidGenerateFunc() },
20+
{ typeof(string), () => StringGenerateFunc() },
21+
{ typeof(long), () => LongGenerateFunc() },
22+
{ typeof(int), () => IntGenerateFunc() }
23+
};
24+
25+
/// <summary>
26+
/// Guid 生成函数,允许外部自定义生成方式。
1627
/// </summary>
1728
public static Func<Guid> GuidGenerateFunc { get; set; } = Guid.NewGuid;
1829

30+
/// <summary>
31+
/// String ID 生成函数(默认为 Guid 字符串)。
32+
/// </summary>
33+
public static Func<string> StringGenerateFunc { get; set; } = () => GuidGenerateFunc().ToString();
34+
35+
/// <summary>
36+
/// Long ID 生成函数(默认为雪花 ID)。
37+
/// </summary>
38+
public static Func<long> LongGenerateFunc { get; set; }
39+
40+
/// <summary>
41+
/// Int ID 生成函数(默认不支持)。
42+
/// </summary>
43+
public static Func<int> IntGenerateFunc { get; set; } = () => throw new InvalidOperationException("不支持 Int 作为 ID,请使用 Guid, string 或 long。");
44+
45+
/// <summary>
46+
/// 生成唯一标识 ID,支持 Guid、string、long 类型。
47+
/// </summary>
48+
/// <typeparam name="TKey">ID 类型</typeparam>
49+
/// <returns>生成的 ID 值</returns>
50+
public static TKey CreateKey<TKey>()
51+
{
52+
if (_idGenerators.TryGetValue(typeof(TKey), out var generator))
53+
return (TKey)generator();
54+
throw new InvalidOperationException($"不支持的 ID 类型: {typeof(TKey)},请使用 Guid, string, long。");
55+
}
56+
57+
/// <summary>
58+
/// 判断实体类型是否为多租户实体。
59+
/// </summary>
60+
public static Func<IEntity, IEntity, bool> IsMultiTenantEntity { get; set; } = (_, _) => false;
61+
62+
/// <summary>
63+
/// 在不同租户下是否允许相同 ID 作为相等的规则(默认:不允许)。
64+
/// </summary>
65+
public static Func<IEntity, IEntity, bool> AllowSameIdAcrossTenants { get; set; } = (_, _) => false;
66+
1967
/// <summary>
2068
/// 判断两个 <see cref="IEntity"/> 实例是否相等。
2169
/// </summary>
@@ -39,7 +87,9 @@ public static bool EntityEquals(IEntity entity1, IEntity entity2)
3987
if (!typeOfEntity1.IsAssignableFrom(typeOfEntity2) && !typeOfEntity2.IsAssignableFrom(typeOfEntity1))
4088
return false;
4189

42-
// 多租户委托检查
90+
// 多租户检查
91+
if (IsMultiTenantEntity(entity1, entity2))
92+
return AllowSameIdAcrossTenants(entity1, entity2);
4393

4494
// 瞬时对象不视为相等
4595
if (HasDefaultKeys(entity1) && HasDefaultKeys(entity2))
@@ -48,7 +98,7 @@ public static bool EntityEquals(IEntity entity1, IEntity entity2)
4898
// 如果键数量不匹配,则不相等
4999
var entity1Keys = entity1.GetKeys();
50100
var entity2Keys = entity2.GetKeys();
51-
if(entity1Keys.Length!=entity2Keys.Length)
101+
if (entity1Keys.Length != entity2Keys.Length)
52102
return false;
53103

54104
// 逐个比较主键值
@@ -97,7 +147,7 @@ public static bool IsEntity(Type type)
97147
/// <remarks>
98148
/// 用于判断一个类型是否为值对象类型。默认实现为检查是否继承自<see cref="ValueObjectBase{T}"/>。
99149
/// </remarks>
100-
public static Func<Type, bool> IsValueObjectPredicate = type => typeof(ValueObjectBase<>).IsAssignableFrom(type);
150+
public static Func<Type, bool> IsValueObjectPredicate { get; set; } = type => typeof(ValueObjectBase<>).IsAssignableFrom(type);
101151

102152
/// <summary>
103153
/// 是否值对象类型

0 commit comments

Comments
 (0)