我有一个对象,他的实例是在运行时创建的,如下所示:
var type = GetTypeFromAssembly(typeName, fullNameSpaceType);
var instanceOfMyType = Activator.CreateInstance(type);
ReadObject(instanceOfMyType.GetType().GetProperties(), instanceOfMyType, fullNameSpaceType);
return instanceOfMyType;
我需要通过 Id 找到一个对象,为此我构建了以下方法:
var parameter = Expression.Parameter(typeof(object));
var condition =
Expression.Lambda<Func<object, bool>>(
Expression.Equal(
Expression.Property(parameter, theEntity.GetType().GetProperty("Id").Name),
Expression.Constant(id, typeof(TKey))
), parameter
).Compile();
但是会抛出一个未处理的异常:
The instance property 'Id' is not defined for type 'System.Object'
那么,我如何构建一个带有 T 的 Func,其中 T 是在运行时设置的?像这样:
var parameter = Expression.Parameter(typeof(MyObjectReflectionRuntimeType>));
var condition =
Expression.Lambda<Func<MyObjectReflectionRuntimeType, bool>>(
Expression.Equal(
Expression.Property(parameter, theEntity.GetType().GetProperty("Id").Name),
Expression.Constant(id, typeof(TKey))
), parameter
).Compile();
更新 [没有 Entity Framework 的解决方案]
我做了如下:
public interface IBaseObject<T>
{
T Id { get; set; }
}
public class AnyClass : IBaseObject<Guid>
{
public Guid Id { get; set; }
}
var parameter = Expression.Parameter(typeof(IBaseObject<Guid>));
var id = Guid.NewGuid();
var theEntity = new AnyClass();
var theList = new List<AnyClass>
{
new AnyClass
{
Id = Guid.NewGuid()
},
new AnyClass
{
Id = Guid.NewGuid()
},
new AnyClass
{
Id = id
},
new AnyClass
{
Id = Guid.NewGuid()
}
};
var condition =
Expression.Lambda<Func<IBaseObject<Guid>, bool>>(
Expression.Equal(
Expression.Property(parameter, theEntity.GetType().GetProperty("Id").Name),
Expression.Constant(id, typeof(Guid))
), parameter
).Compile();
var theMetaData = theList.Where(condition).FirstOrDefault();
但它在 Entity Framework 上崩溃,因为 IBaseObject<T>
它不是上下文的一部分:( ...
[更新两个]
我找到了这样的解决方案,但它不是最优的(感谢@Serge Semenov):
var parameter = Expression.Parameter(typeof(object));
var entity = Expression.Convert(parameter, theEntity.GetType());
var condition =
Expression.Lambda<Func<object, bool>>(
Expression.Equal(
Expression.Property(entity, theEntity.GetType().GetProperty("Id").Name),
Expression.Constant(id, typeof(TKey))
), parameter
).Compile();
var theObject = await _unitOfWork.Set(theEntity.GetType()).ToListAsync();
return theObject.FirstOrDefault(condition);
我说这不是最好的方法,因为不是使用 await _unitOfWork.Set(theEntity.GetType()).ToListAsync();
我想使用:await _unitOfWork.Set(theEntity.GetType()).FirstOrDefaultAsync();
但它不起作用......
有什么想法吗??
最佳答案
你传递了一个 object
给你的Func<>
, 但访问 Id
在其他类型上定义的属性。
最简单的解决方法是转换 object
类型 T
然后访问其属性,就像在 C# 中一样 ((T)obj).Id
:
var parameter = Expression.Parameter(typeof(object));
var entity = Expression.Convert(parameter, theEntity.GetType());
...
Expression.Property(entity, theEntity.GetType().GetProperty("Id").Name),
...
关于c# - T 未知时如何创建 Func<T, bool>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40030990/