I have an object that his instance is created on runtime like this:
var type = GetTypeFromAssembly(typeName, fullNameSpaceType);
var instanceOfMyType = Activator.CreateInstance(type);
ReadObject(instanceOfMyType.GetType().GetProperties(), instanceOfMyType, fullNameSpaceType);
return instanceOfMyType;
And I need to find an object by Id, for this I have built the follow method:
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();
But throws an unhandled exception that says:
The instance property 'Id' is not defined for type 'System.Object'
So, how I can built a Func with T where T is seted on runtime ?? Something like this:
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();
UPDATE [Solution with out Entity Framework]
I have made the follow:
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();
But it crashes on Entity Framework because the IBaseObject<T>
its not part of the context :( ...
[UPDATE TWO]
I have find a solution like this but it not optimal (Thanks to @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);
I'm say that is not the best way because instead of use await _unitOfWork.Set(theEntity.GetType()).ToListAsync();
I would like to use: await _unitOfWork.Set(theEntity.GetType()).FirstOrDefaultAsync();
but it does not work ...
Any idea ??