3
我試圖建立一個表達式與泛型類型參數個數可變創建通用Tuple<>
實例變量數量的元組。表達對創建的泛型類型參數
生成的Tuple<>
實例的想法是基於其上具有KeyAttribute
的屬性爲實體類型動態創建組合鍵值。然後組合鍵將被用作Dictionary<object, TEntity>
中的鍵。所以lambda表達式應該建立一定的實體類型和拉姆達會被調用,傳遞的TEntity
一個實例來取回一個Tuple<>
形式的組合鍵。
例實體模型
public class MyEntityModel
{
[Key]
public string Key1 { get; set; }
[Key]
public Guid Key2 { get; set; }
public int OtherProperty { get; set; }
}
表達什麼應該做
public Func<MyEntityModel, object> BuildKeyFactory()
{
// This is how the LambdaExpression should look like, but then for a generic entity type instead of fixed to MyEntityModel
return new Func<MyEntityModel, object>(entity => new Tuple<string, Guid>(entity.Key1, entity.Key2));
}
但當然的實體模型需要一個泛型類型。
我有什麼到目前爲止
public Func<TEntity, object> BuildKeyFactory<TEntity>()
{
var entityType = typeof(TEntity);
// Get properties that have the [Key] attribute
var keyProperties = entityType.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(x => x.GetCustomAttribute(typeof(KeyAttribute)) != null)
.ToArray();
var tupleType = Type.GetType($"System.Tuple`{keyProperties.Length}");
if (tupleType == null) throw new InvalidOperationException($"No tuple type found for {keyProperties.Length} generic arguments");
var keyPropertyTypes = keyProperties.Select(x => x.PropertyType).ToArray();
var tupleConstructor = tupleType.MakeGenericType(keyPropertyTypes).GetConstructor(keyPropertyTypes);
if (tupleConstructor == null) throw new InvalidOperationException($"No tuple constructor found for key in {entityType.Name} entity");
// The following part is where I need some help with...
var newTupleExpression = Expression.New(tupleConstructor, keyProperties.Select(x => ????));
return Expression.Lambda<Func<TEntity, object>>(????).Compile();
}
正如你所看到的,我無法弄清楚如何我需要爲傳遞給Expression.New()
調用(可能是一些與Expression.MakeMemberAccess(Expression.Property())
創建屬性表達式,但不知道如何從lambda參數中傳遞TEntity
實例),以及如何通過Expression.Lambda
調用將其鏈接起來。任何幫助將不勝感激!