1
EDIT
My problem is this.
I need to generate a lambda expression that is of a type that I will only know at the time of execution, IE, the type to be used will be passed in the parameter classType of the controller below. But the type I create in the Runtime method is not compatible with the expression I need to create.
NOTE: The Whereequalsnontyped method recognizes the type of the generated context, but when using typeof() it returns the type 'System.Object'.
Below is the controller calling the method to get the class type dynamically:
[Route ("{classtype} / {id} / {key}")]
public string GetObter (int id, string key, string classtype)
{
var attach = servico.ObterDinamico (classtype, id, includes);
return attach.RetrieveFiles (key);
}
}
Method that creates context from the past type:
public object ObterDinamico(string typeName, int id, string [] includes = null)
{
Type tableEntity = Type.GetType ("My_Domain." + TypeName + ", My_Domain");
IEnumerable <dynamic> dbObject = (IEnumerable <dynamic>)
typeof (DbContext) .GetMethod ("Set", Type.EmptyTypes)
.MakeGenericMethod (tableEntity)
.Invoke (bd, null);
IQueryable <dynamic> result = dbObject.AsQueryable ();
if (includes! = null)
foreach (string i in includes)
result = result.Include (i);
return result.WhereEqualsNonTyped ("id", id, typeName);
}
lambda method that does not recognize the type T in this case, so does not generate the expression as accurate:
public static IQueryable <T> WhereEqualsNonTyped <T> (this IQueryable <T> query, string propertyName, dynamic value, string typeName)
{
try
{
//sem essa instancia do Type para gerar o tipo dinâmico que preciso
//o método sempre dá erro assim que chega na linha
//MemberExpression
var type = Type.GetType ("My_Domain." + typeName + ", My_Domain");
ParameterExpression parameter = Expression.Parameter (type, "type");
MemberExpression property = Expression.Property (parameter, propertyName);
BinaryExpression expression = Expression.Equal (property, Expression.Constant (value, value.GetType ()));
Expression <Func <T, bool >> predicate = Expression.Lambda <Func <T, bool >> (expression, parameter);
return query.Where (predicate);
}
catch (Exception e)
{
return query;
}
}
Currently the error that is generated is:
Parameterexpression of type 'My_domain.my_object' cannot be used to delegate the System.Object type parameter'
Whereequals is the problem?
– novic
That, the Get method accesses setClass and creates an instance of the object at runtime. However, when the Whereequals class is going to be executed, it cannot access the dynamic class created at runtime by accessing an instance of the Object class.
– Guilherme Caixeta
And when going to perform the search for the generic attribute passed is generated the inaccessible attribute error. And the lambda expression is not generated.
– Guilherme Caixeta
Has a code that is not used in Get
SetClass
, has a code withdynamic
which in my opinion will not work either, maybe the problems are before, but, failed to say what the mistake, have to put in question?– novic
if (!string.IsNullOrEmpty(classType)) SetClass(classType);
what does this code do? andIQueryable<dynamic> result = model?.AsQueryable();
here is also wrong, where is it used and why did you do so? Reminder: the only correct code ispublic static IQueryable<T> WhereEquals<T>
this is right, it is unnecessary because with the expressions already has this, but, it is correct!– novic
The setClass takes a string and creates an object instance through the string that is passed, so far so good. Iqueryable<Dynamic> result = model?. Asqueryable(). This section does the following, after generating the instance of.
– Guilherme Caixeta
I don’t know the general context, but maybe that’s what’s missing, the way it’s still giving doubts about the other methods implemented! still explain more in question, put all the code is already a good start.
– novic
I updated the question to clarify the problem.
– Guilherme Caixeta
So you did an extension method, so why instantiate a class that comes from the method itself? has sausage in your code, from a checked that is not valid... !!!
– novic
Only then the code already works: as the code should be https://ideone.com/jnDd7p (just look at the code the error of the site is normal)
– novic
This part I put to check if the object I want was being generated correctly, because when I access the Whereequals method it loses the reference of the object and it becomes an instance of the 'System.Object'. It was bad, my mistake not having explained why of is generating again in the Whereequals method.
– Guilherme Caixeta
So, I tested only the extension method in a code of its own and it works, the problem is not Whereequals is the previous method that in my view the two are unnecessary, where to use it?
– novic
@Virgilionovic when the object type is well specified in the class that calls the Whereequals method it works well, the problem only occurs when I have to generate the object instance in Runtime, as in the example. Because the method cannot identify this dynamic object.
– Guilherme Caixeta
William If the object you want to generate isn’t in the context class it won’t work, your code is unnecessary without having a clearer need, see, I’m trying to show you that what you’re doing is bad practice, because so far it has not shown me a functional point and where it will use and for what need, is an object of the ORM class, it must exist if it causes no errors.
– novic
@Virgilionovic, let’s start with my need for this method. I have several objects that act as "combos", that is, they are composed only by name and id, and in the other variable. And instead of generating various contexts that act to perform the research of each of these objects, this method was built for this. But in the Get method where it is instantiated I found the following problem: the whereEquals method fails to identify the type of iqueryable that is generated in Runtime.
– Guilherme Caixeta
the error is clear
IQueryable de dynamic
is a layerEntity Framework
that needs a definite type will not work! already begins the problem there, about contexts, maybe there are better ways to do this and for sure exists.– novic
@Virgilionovic updated the question, now it contains all the methods used.
– Guilherme Caixeta
Look maybe like this
public static dynamic GetInstance
change topublic static T GetInstance<T>
and on the last linereturn Activator.CreateInstance<T>(Type.GetType(fullName));
already change this well to a Generic object that must be contained in its ORM class. I took another look generated , if you are repeating too much code can summarize all this, but, it is a general way maybe this modification helps you– novic
@Virgilionovic I would do that, but the way I want the method to work it becomes unfeasible. Because the type T will be known at the time of execution, it comes as a front end parameter. From this I have to generate an instance of this object and perform the search.
– Guilherme Caixeta
I really can’t understand you, because now the kind of data comes from
Front-End
strange this, but, as there is no way to move because it is a local problem and without reproduction is complicated in me help you, sorry!– novic
In fact the type of combo to be worked always came from the front, but I did not find it necessary to pass this part here. That’s why I have to access the Whereequals method as much as possible. But I appreciate the help already.
– Guilherme Caixeta
@Virgilionovic managed to solve the problem in a simple way. Thanks for the help.
– Guilherme Caixeta