| Author |
Share Topic Topic Search Topic Options
|
jolemaiavix
Newbie
Joined: 26-Oct-2010
Posts: 5
|
Post Options
Quote Reply
Topic: Variable Linq 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?
|
 |
sbelini
IdeaBlade
Joined: 13-Aug-2010
Location: Oakland
Posts: 786
|
Post Options
Quote Reply
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 online and with your DevForce installation).
Edited by sbelini - 26-Oct-2010 at 2:40pm
|
 |
jolemaiavix
Newbie
Joined: 26-Oct-2010
Posts: 5
|
Post Options
Quote Reply
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.
|
 |
sbelini
IdeaBlade
Joined: 13-Aug-2010
Location: Oakland
Posts: 786
|
Post Options
Quote Reply
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
Edited by sbelini - 28-Oct-2010 at 12:30pm
|
 |
jolemaiavix
Newbie
Joined: 26-Oct-2010
Posts: 5
|
Post Options
Quote Reply
Posted: 29-Oct-2010 at 5:57am |
|
which namespaces need?
|
 |
sbelini
IdeaBlade
Joined: 13-Aug-2010
Location: Oakland
Posts: 786
|
Post Options
Quote Reply
Posted: 29-Oct-2010 at 9:13am |
IdeaBlade.Linq
You can find aditional information about PredicateBuilder at the API Documentation available online and installed with DevForce2010.
|
 |
jolemaiavix
Newbie
Joined: 26-Oct-2010
Posts: 5
|
Post Options
Quote Reply
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?
|
 |
sbelini
IdeaBlade
Joined: 13-Aug-2010
Location: Oakland
Posts: 786
|
Post Options
Quote Reply
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.
Edited by sbelini - 29-Oct-2010 at 10:51am
|
 |
jolemaiavix
Newbie
Joined: 26-Oct-2010
Posts: 5
|
Post Options
Quote Reply
Posted: 08-Nov-2010 at 4:47am |
|
worked perfectly! Another question: how would for the "ORDER BY" also be dynamic as the WHERE?
|
 |
sbelini
IdeaBlade
Joined: 13-Aug-2010
Location: Oakland
Posts: 786
|
Post Options
Quote Reply
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.
|
 |
gkneo
Newbie
Joined: 23-Jun-2010
Posts: 21
|
Post Options
Quote Reply
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
|
 |