Print Page | Close Window

Variable Linq

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce 2010
Forum Discription: For .NET 4.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=2263
Printed Date: 29-Jul-2026 at 11:13am


Topic: Variable Linq
Posted By: jolemaiavix
Subject: Variable Linq
Date Posted: 26-Oct-2010 at 12:20pm
I need to run the linq below:

IEntityQuery<Employee> qry = (IEntityQuery<Employee>)_entityManager.BasePersons
                .Include(Employee.PathFor(b => b.Address))
                .Include(Employee.PathFor(b => b.Address.Country))
                .Where(b => b.Name.Contains(pValue));

Being that I need to replace the code "Where (b => b.Name.Contains (pvalue))" for "Where (MyVariable)". MyVariable will contain "Name == 'test'." Is it possible? How do I?



Replies:
Posted By: sbelini
Date Posted: 26-Oct-2010 at 2:34pm
Hi jolemaiavix,
 
You can build queries dynamically by using the Predicatebuilder.
In your case you will parse your MyVariable string and build the query according with the string. (i.e. "Name == 'test'" or Name.Contains("test") )
 
You can find detailed information about PredicateBuilder in our API documentation (available http://drc.ideablade.com/ApiDocumentation/ - online and with your DevForce installation).


Posted By: jolemaiavix
Date Posted: 28-Oct-2010 at 4:57am
I can not use "contains". The contents of MyVariable will be filled on a selection by an end user. The content of it can be "Name == 'test'" or "Type == 2" or anything else.


Posted By: sbelini
Date Posted: 28-Oct-2010 at 12:30pm
Hi,
 
I mentioned the "contains" example because you had it initially in your snippet.
Yet, the PredicateBuilder is what you are looking for.
 
Suppose MyVariable is "Name == 'test'":
 
  var MyVariable = "Name == 'test'";
  var strings = MaVariable.Split(' ');
  var expr1 = PredicateBuilder.Make(typeof(Employee), strings[0].Trim()
    ,FilterOperator.IsEqualTo
    ,Int32.Parse(strings[2].Trim('\'')));
  var exprFunc = (Expression<Func<Employee, bool>>)expr1.ToLambdaExpression();
  var query = mgr.Employees.Where(exprFunc);
  var results = query.Execute();
 
 
I hope it helps


Posted By: jolemaiavix
Date Posted: 29-Oct-2010 at 5:57am
which namespaces need?


Posted By: sbelini
Date Posted: 29-Oct-2010 at 9:13am
IdeaBlade.Linq
 
You can find aditional information about PredicateBuilder at the API Documentation available http://drc.ideablade.com/ApiDocumentation/ - online and installed with DevForce2010.


Posted By: jolemaiavix
Date Posted: 29-Oct-2010 at 9:49am
The code looks like this:

    public override void Inicializar(string texto)
    {
      ListaRegistros = new ObservableCollection<T>();
      ListaRegistros.CollectionChanged += ListaRegistros_CollectionChanged;

      _propriedadeDinamicaBusy = _propriedadeIsBusyMaster;

      AthenasEntityManager.Fetching += (s, e) =>
      {
        IsBusy = true;
      };

      AthenasEntityManager.Queried += (s, e) =>
      {
        IsBusy = false;
        _propriedadeDinamicaBusy = _propriedadeIsBusyDetail;
      };

      Entity instancia = (Entity)Activator.CreateInstance(typeof(T));

      var MyVariable = texto;
      var strings = MyVariable.Split(' ');
      var expr1 = PredicateBuilder.Make(typeof(T), strings[0].Trim()
        , FilterOperator.IsEqualTo
        , Int32.Parse(strings[2].Trim('\'')));
      var exprFunc = (Expression<Func<T, bool>>)expr1.ToLambdaExpression();

      var query = new EntityQuery<T>(instancia.EntityAspect.EntitySetName, AthenasEntityManager).Where(exprFunc);

      query.ExecuteAsync(
        args =>
        {
          if (!Excecao.TratarRetornoCallback(args))
            return;

          args.Results.ForEach(ListaRegistros.Add);

          RegistroCorrenteLocal = ListaRegistros.FirstOrDefault();

          if (AoCarregarRegistros != null)
          {
            AoCarregarRegistros(this, new EventArgs());
          }
        });

      //var teste = ListaRegistros.Where<string>("","");
    }

Type T is inherited in the call to "ViewModelCadastro.Inicializar("codigo == 1");".

      TipoDominioType = Util.GetAssemblyType("Dominio." + TipoDominio);
      if (TipoDominioType == null)
      {
        Excecao.ExibirMensagem(string.Format("Não foi possível encontrar o domínio {0}.", TipoDominio));
        return;
      }

      ViewModelCadastro = (Activator.CreateInstance(typeof(ViewModel<>).MakeGenericType(new Type[] { TipoDominioType })) as IViewModel);
      if (ViewModelCadastro == null)
      {
        return;
      }
      ViewModelCadastro.Inicializar("codigo == 1");

The red line is returning null to exprFunc. Where's the error?



Posted By: sbelini
Date Posted: 29-Oct-2010 at 10:48am
I couldn't reproduce the issue here.
Was expr1 created properly?
 
Here's a testunit against NorthwindIB which executed with no issues:
 
[TestMethod]
public void TestPredicateBuilder2() {
  var mgr = new NorthwindIBEntityManager();
  mgr.AuthorizedThreadId = null;
  //var MyVariable = "EmployeeID == 1";
  var MyVariable = "LastName == 'Davolio'";
  var strings = MyVariable.Split(' ');
  var expr1 = PredicateBuilder.Make(typeof(Employee), strings[0].Trim()
    , FilterOperator.IsEqualTo
    , strings[2].Trim('\''));
  var exprFunc = (Expression<Func<Employee, bool>>)expr1.ToLambdaExpression();
  Entity instancia = (Entity)Activator.CreateInstance(typeof(Employee));
  var query = new EntityQuery<Employee>(instancia.EntityAspect.EntitySetName, mgr).Where(exprFunc);
  var emps = query.Execute();
}
 
 
I suggest you create a simple test, and gradually add complexity to it, so you can isolate what's causing the issue.


Posted By: jolemaiavix
Date Posted: 08-Nov-2010 at 4:47am
worked perfectly! Another question: how would for the "ORDER BY" also be dynamic as the WHERE?


Posted By: sbelini
Date Posted: 15-Nov-2010 at 9:24am
Hi jolemaiavix,
 
Unfortunatelly, using OrderBy dynamically is not possible yet, but we have it in our list of features to be implemented.
 
sbelini.


Posted By: gkneo
Date Posted: 02-Dec-2010 at 1:50am
Hi, jolemaiavix.

Why don't you try the following:

   foreach (var fieldName in _orderFields)
                {
                    Type t = _filterEntity.EntityAspect.GetDataProperty(fieldName).DataType;
                    if (t == typeof(String))
                        query = query.OrderBy(GetMember<Employee, string>(_filterEntity, fieldName));
                    else if (t == typeof(Int32))
                        query = query.OrderBy(GetMember<Employee, Int32>(_filterEntity, fieldName));
                }



and the GetMember method:
 public static System.Linq.Expressions.Expression<Func<T, T2>> GetMember<T, T2>(T entity, string memberName)
        {
            System.Linq.Expressions.ParameterExpression pe =
                System.Linq.Expressions.Expression.Parameter(typeof(T), "p");
            return (System.Linq.Expressions.Expression<Func<T, T2>>)
                System.Linq.Expressions.Expression.Lambda(typeof(Func<T, T2>),
                    System.Linq.Expressions.Expression.Property(pe, memberName), pe);
        }

_filterEntity is a dummy instance (in this case of type Employee) used to retrieve information about the queried type.  (I think may be another way to do this without using a dummy instance).  

_orderFields is a list of string which values are the name of the fields to use in the "order by" clause.

query is a IEntityQuery<Employee>

Guillermo




Print Page | Close Window