Enhance EntityHelper's TrySetId method.

Resolve #3461
pull/3490/head
maliming 5 years ago
parent 86aee14c88
commit fb8dee5ccc

@ -1,5 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using JetBrains.Annotations;
@ -95,32 +97,40 @@ namespace Volo.Abp.Domain.Entities
var lambdaBody = Expression.Equal(leftExpression, rightExpression);
return Expression.Lambda<Func<TEntity, bool>>(lambdaBody, lambdaParam);
}
private static readonly ConcurrentDictionary<string, PropertyInfo> CachedPropertyInfo =
new ConcurrentDictionary<string, PropertyInfo>();
public static void TrySetId<TKey>(
IEntity<TKey> entity,
Func<TKey> idFactory,
bool checkForDisableGuidGenerationAttribute = false)
{
//TODO: Can be optimized (by caching per entity type)?
var entityType = entity.GetType();
var idProperty = entityType.GetProperty(
nameof(entity.Id)
);
var property = CachedPropertyInfo.GetOrAdd(
entity.GetType().FullName + checkForDisableGuidGenerationAttribute, () =>
{
var entityType = entity.GetType();
var idProperty = entityType.GetProperties()
.Where(x => x.GetSetMethod(true) != null)
.FirstOrDefault(x => x.Name == nameof(entity.Id));
if (idProperty == null || idProperty.GetSetMethod(true) == null)
{
return;
}
if (idProperty == null)
{
return null;
}
if (checkForDisableGuidGenerationAttribute)
{
if (idProperty.IsDefined(typeof(DisableIdGenerationAttribute), true))
{
return;
}
}
if (checkForDisableGuidGenerationAttribute)
{
if (idProperty.IsDefined(typeof(DisableIdGenerationAttribute), true))
{
return null;
}
}
return idProperty;
});
idProperty.SetValue(entity, idFactory());
property?.SetValue(entity, idFactory());
}
}
}

@ -1,4 +1,5 @@
using System;
using System.ComponentModel;
using Shouldly;
using Xunit;
@ -33,6 +34,15 @@ namespace Volo.Abp.Domain.Entities
myEntityDisablesIdGeneration.Id.ShouldBe(default);
}
[Fact]
public static void SetId_NewIdFromBaseClass()
{
var idValue = Guid.NewGuid();
var myNewIdEntity = new NewIdEntity();
EntityHelper.TrySetId(myNewIdEntity, () => idValue, true);
myNewIdEntity.Id.ShouldBe(idValue);
}
private class MyEntityDerivedFromAggregateRoot : AggregateRoot<Guid>
{
@ -53,5 +63,14 @@ namespace Volo.Abp.Domain.Entities
[DisableIdGeneration]
public override Guid Id { get; protected set; }
}
public class NewIdEntity : Entity<Guid>
{
public new Guid Id
{
get => base.Id;
set => base.Id = value;
}
}
}
}

Loading…
Cancel
Save