我有一个对象,他的实例是在运行时创建的,如下所示:
MemoryStream
我需要通过Id找到一个对象,为此我构建了以下方法:
var type = GetTypeFromAssembly(typeName, fullNameSpaceType);
var instanceOfMyType = Activator.CreateInstance(type);
ReadObject(instanceOfMyType.GetType().GetProperties(), instanceOfMyType, fullNameSpaceType);
return instanceOfMyType;
但抛出一个未处理的异常,说:
实例属性' Id'未定义类型' System.Object'
那么,我如何用T构建一个Func,其中T在运行时被设置?像这样:
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();
更新[无实体框架的解决方案]
我做了以下:
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();
但它在实体框架上崩溃,因为 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();
不是上下文的一部分:( ...
[更新二]
我找到了这样的解决方案但不是最优的(感谢@Serge Semenov):
IBaseObject<T>
我说这不是最好的方式,因为我不想使用 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();
但它不起作用......
任何想法??
答案 0 :(得分:0)
您将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),
...