For example, the following method does not work whether the method is generic or the controller is generic:
public BaseOutput GetByNameOrId<T>(int id, string name)
where T : CommonEntity<T>, new()
{
BaseOutput output = new BaseOutput();
using (var repository = Db.GetRepository<T>())
{
output.Result = repository.FirstOrDefault(x => x.Name == name || x.Id == id);
}
return output;
}
I tried to use a method like this but don’t know how to convert className
to T
:
public BaseOutput GetByNameOrId(string className, int id, string name)
{
BaseOutput output = new BaseOutput();
// How to convert className to T ?
using (var repository = Db.GetRepository<T>())
{
output.Result = repository.FirstOrDefault(x => x.Name == name || x.Id == id);
}
return output;
}
I succeeded in the following way, but it was too troublesome, because there may be other methods that need to use generics later.
public BaseOutput GetByNameOrId(string className, int id, string name)
{
BaseOutput output = new BaseOutput();
// 获取类的 Type 对象
Type targetType = Type.GetType($"MCS.Object.{className},MCS.Object");
if (targetType != null)
{
var v = typeof(Db).GetMethods().Where(x => x.Name == "GetRepository" && x.GetGenericArguments().Length == 1 && x.GetParameters().Length == 1).ToList();
MethodInfo GetRepository = typeof(Db).GetMethods().FirstOrDefault(x => x.Name == "GetRepository" && x.GetGenericArguments().Length == 1 && x.GetParameters().Length == 1).MakeGenericMethod(targetType);
var repository = GetRepository.Invoke(null, new object[] { default });
MethodInfo FirstOrDefault = repository.GetType().GetMethods().FirstOrDefault(x => x.Name == "FirstOrDefault" && x.GetParameters().Length == 2);
// 创建动态表达式
ParameterExpression param = Expression.Parameter(targetType, "x");
Expression idComparison = Expression.Equal(
Expression.Property(Expression.Convert(param, targetType), "Id"),
Expression.Constant(id));
Expression nameComparison = Expression.Equal(
Expression.Property(Expression.Convert(param, targetType), "Name"),
Expression.Constant(name));
Expression orExpression = Expression.OrElse(idComparison, nameComparison);
var filter = Expression.Lambda(orExpression, param);
output.Result = FirstOrDefault.Invoke(repository, new object[] { filter, default });
}
else
{
Console.WriteLine($"Type {className} not found.");
}
return output;
}
I hope there is a way to convert classname
to T
for generics