Click here to Skip to main content
15,887,267 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hey guys what's up?

We are now working on a project in my company (C # & ASP.Net) and in one of the pages, there is a mechanism which pulled some data from a table using WCF.

So far So good!

that data is stored inside a DTO class (let's name it Tikun94ActualPerformanceSummaryDTO) and eventually i converts it to an IEnumerable object like that:
IEnumerable<Tikun94ActualPerformanceSummaryDTO> filtered = this.Tikun94Summaries as IEnumerable<Tikun94ActualPerformanceSummaryDTO>;

(Tikun94Summaries is an object of type Tikun94ActualPerformanceSummaryDTO).

Now, These data are viewed through a table on the page and the user can filter the table using a few options that I give him.
While pressing the 'Submit' button, i want to iterate through the existing "filtered" (of type IEnumerable which I created before) and filter it by the values given me from the user.

For each value given from the user, I need to set a Where clause that filter "filtered" again and again. Now, because I do not want to query over and over again on the same IEnumerable "filtered" , I want to build the Where dynamically
and than run it only one time.

Lets see some code:
IEnumerable<Tikun94ActualPerformanceSummaryDTO> filtered = this.Tikun94Summaries as IEnumerable<Tikun94ActualPerformanceSummaryDTO>;
            IQueryable<Tikun94ActualPerformanceSummaryDTO> queryableData = filtered.AsQueryable();

Here (above), as you can see, i start by converting the IEnumerable object into IQueryable object in order to do the following:

string query = "filtered.Where(";

Now, i start checking the values given from the user and set the Where according to them using Switch Case (Let's take 2 cases as an example):
C#
#region OperatorLineId

switch (cmbLine.SelectedValue)
            {
                case "0":
                    query += += "u => u.OperatorLineId == u.OperatorLineId  ";
                    break;
                default:
                    query += "u => u.OperatorLineId == Convert.ToInt32(cmbLine.SelectedValue) ";
                    break;
            }
#endregion

#region ExclusivityLine 
switch (ddlExclusivityLine.SelectedValue)
            {
                case "0":
                    query += "AND u => u.ExclusivityLine == u.ExclusivityLine ";
                    break;
                default:
                    query += "AND u => u.ExclusivityLine == ddlExclusivityLine.SelectedValue )";
                    break;
            }
            #endregion

var externals = new Dictionary<string, object>();
            externals.Add("filtered", queryableData);

And this is where i get the EXECPTION :-( :
var expression = System.Linq.Dynamic.DynamicExpression.Parse(typeof(IQueryable<Tikun94ActualPerformanceSummaryDTO>), query, new[] {externals});

Exception message:
"No property or field 'u' exists in type 'Tikun94ActualPerformanceSummaryDTO'"

I have a few guesses as to what I was doing wrong. Maybe i'm trying to use lambda expression where I'm not supposed to and maybe i'm not accessing the items inside the DTO cuurectly. Hoe can i access the values inside the DTO? maybe i'm not suppose to?

Eventually, i want to build that Where clause dynamically (in some of the switch cases i have to use operator '>' or '<').

I guess I have more than one error in writing this algorithm and I'd love to know what the correct syntax for writing this operation.

This is the Tikun94ActualPerformanceSummaryDTO class (There are of course many more parameters there, but here it's just for example):
using System;
using WcfSerialization = global::System.Runtime.Serialization;

namespace OpsReporting.DataContracts
{
    [WcfSerialization::DataContract(Namespace = "urn:OperatorsReporting.ServiceContracts", Name = "Tikun94ActualPerformanceParamDTO")]
	public partial class Tikun94ActualPerformanceSummaryDTO
    {
        public int operatorLineId;
        public string exclusivityLine;
        
        [WcfSerialization::DataMember(Name = "OperatorLineId", IsRequired = true, Order = 6)]
        public int OperatorLineId
        {
            get { return operatorLineId; }
            set { operatorLineId = value; }
        }

        [WcfSerialization::DataMember(Name = "ExclusivityLine", IsRequired = true, Order = 8)]
        public string ExclusivityLine
        {
            get { return exclusivityLine; }
            set { exclusivityLine = value; }
        }    
}



Thank you very much!

What I have tried:

Lots: see above
Posted
Updated 5-Dec-16 9:19am
v2

1 solution

In dynamic linq, the string parameter passed in is just normal sql, not any lambda expressions, so your condition should be like:

C#
 case "0":
       query += "OperatorLineId = OperatorLineId  ";
       break;
default:
      query += string.Format("OperatorLineId = {0}",Convert.ToInt32(cmbLine.SelectedValue));

var result = filtered.Where(query);


you might want to read this article for more. or consider checking out this article about dynamic Linq to Entities Queries using WCF
 
Share this answer
 
v6
Comments
oronsultan 5-Dec-16 15:32pm    
Dear Ehsan,
thanks for the quick reply.
I tried doing it befor (and tryied it agian after you'r reply) but all i get is this exception:
"Expression of type 'IQueryable`1' expected".
I googled it and couldnt find anything.
BTW, it happens on the same code row as befor. Any idea?
Ehsan Sajjad 5-Dec-16 16:19pm    
your query where clause part should not be string literal, it should be like : `var result = filtered.Where(query);`
oronsultan 5-Dec-16 16:33pm    
it's immposibble to write 'var result = filtered.Where(query);', the 'where' doesnt accept string. can u help me please with syntax?
oronsultan 5-Dec-16 16:33pm    
it's immposibble to write 'var result = filtered.Where(query);', the 'where' doesnt accept string. can u help me please with syntax?
Ehsan Sajjad 6-Dec-16 6:29am    
if you have added reference to DynamicLinq, then add the using on top the class, you should be able to use the Where method which takes string as input

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900