Selecting a variable value with Linq

D

David

Hi all,

I have a query that is return items...

var q = from s in dc.mytable
select new
{
myType = (string)field
myVal = (string)Val
};

So, I am looping through something else... the loop operator could be for
the field or Val...

Here is what I am trying to achieve...

string selector = "Val";

Label1.Text = q.Select(selector);

Basically, what I am trying to do is to have a variable, selector, then use
that to determine which column I want out of Linq query.

How do I do this.

--
Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available
 
P

Pavel Minaev

Hi all,

I have a query that is return items...

var q = from s in dc.mytable
    select new
    {
       myType = (string)field
       myVal = (string)Val
    };

So, I am looping through something else... the loop operator could be for
the field or Val...

Here is what I am trying to achieve...

string selector = "Val";

Label1.Text = q.Select(selector);

Basically, what I am trying to do is to have a variable, selector, then use
that to determine which column I want out of Linq query.

How do I do this.

It seems that you're using LINQ to SQL (though this is a wild guess,
and I may be wrong - please always explicitly state what kind of
"LINQ" it is about!). If so, your best option is to manually build the
Expression<T> object for your query - this would enable you to define
the name of the accessed property at run-time. Specifically, look at
the Expression.Property method (and in general the docs for Expression
and Expression<T>).
 
D

David

Hi Pavel,

I think my query sample here is a Linq to Sql query, but in my particular
case, I am actually querying XML.

I am new to Linq and generics, so please bear with me.

I don't know how to use the Expression<T>... where would I put it, how do I
use it?

--
Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available


Hi all,

I have a query that is return items...

var q = from s in dc.mytable
select new
{
myType = (string)field
myVal = (string)Val
};

So, I am looping through something else... the loop operator could be for
the field or Val...

Here is what I am trying to achieve...

string selector = "Val";

Label1.Text = q.Select(selector);

Basically, what I am trying to do is to have a variable, selector, then
use
that to determine which column I want out of Linq query.

How do I do this.

It seems that you're using LINQ to SQL (though this is a wild guess,
and I may be wrong - please always explicitly state what kind of
"LINQ" it is about!). If so, your best option is to manually build the
Expression<T> object for your query - this would enable you to define
the name of the accessed property at run-time. Specifically, look at
the Expression.Property method (and in general the docs for Expression
and Expression<T>).
 
D

David

Hi Peter,

Let me start again...

I have two queries. Both are querying from XML.

Here is a sample of my code...

var xq = from post in xd.Descendants("form")

select new

{
FormName = (string)post.Attribute("name"),
Fields =
from field in post.Elements("field")
select new
{
Type = (string)field.Attribute("type"),
// EXAMPLE, Type = "text"
Name = (string)field.Attribute("name"),
// EXAMPLE, Name = "email"
Value = (string)field
// EXAMPLE, Value = "(e-mail address removed)"
}

};



var xmap = from dmap in map.Descendants("application")
select new
{
ApplicationName =
(string)dmap.Attribute("id"),

Mappings = from mapping in
dmap.Elements("mapping")
select new
{
XMLField =
(string)mapping.Attribute("XMLField")
}
};


System.Text.StringBuilder fieldValue = new
System.Text.StringBuilder();


foreach (var mapItem in xmap.First().Mappings)
{

if (mapItem.XMLField.Contains(":"))
{
string[] xField = mapItem.XMLField.Split(':');
fieldValue.Append("'" + xq.Select(d =>
xField[1]) + "'");
}
else
{
fieldValue.Append("'" +
xq.First().Fields.Where(a => a.Name == mapItem.XMLField).First() + "'");
}
}


In my foreach loop, I am trying to append to fieldValue. The value in xField
will be something like... form:email, (this is from the xmap query). Now,
What I need to do is to get the value held in the Value field from the xq
query. Basically, the xq query holds all the values. The xmap query defines
where in the xq query to get my value. So, for example... I need to get the
value " me@myemailcom " from the row which has the Name = "email". The text
in Name is what I am putting into the fieldValue.Append.

Imagine like the SQL below...


Col1 = "id";
Col2 = "compname";
MyVal = "dave";

Sql = "select " + Col1 + ", " + Col2 + " from table where " + Col2 + " = '"
+ MyVal + "'"; // (ignore sql injection holes, I would not normally write
like this.)

so, when I come to read it...

Label1.Text = ds.Tables(0).Field(Col2).Value;

(I may have got the syntax slightly wrong)

It is a similar effect that I need to do. Get the column by using a
variable.

--
Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available
Peter Duniho said:
Hi all,

I have a query that is return items...

var q = from s in dc.mytable
select new
{
myType = (string)field
myVal = (string)Val
};

So, I am looping through something else... the loop operator could be for
the field or Val...

Here is what I am trying to achieve...

string selector = "Val";

Label1.Text = q.Select(selector);

Basically, what I am trying to do is to have a variable, selector, then
use
that to determine which column I want out of Linq query.

How do I do this.

As Pavel hints at, your question is very vague. So it's not entirely
clear what an appropriate answer would be.

However, I can tell you that variables are "captured" in a lambda used as
an anonymous method (which is how the "new { myType = (string)field; myVal
= (string)Val; }" is interpreted). Which means you can embed a variable
in your lambda, and then use it to control the behavior of the lambda
after the fact.

So, for example, you could do something like this (making some broad
guesses as to the data types you're actually using here):

string strSelect = null;
var query = from row in dc.mytable
select new
{
myType = strSelect;
myVal = row.Columns[strSelect].ToString();
};

strSelect = "column 1";
foreach (var item in query)
{
// do something with item.myType and item.myVal
}

strSelect = "column 2";
foreach (var item in query)
{
// do something with item.myType and item.myVal
}

Each time you enumerate the "query" reference, it evaluates the lambda
using the current value of "strSelect", so by changing it between the
enumerations, you get different results.

Mind you, this pattern is potentially confusing to those reading the
code. You may find it makes more sense to encapsulate the query in its
own method, and pass a specific value as an argument to be used within the
query, returning the resulting query. The downside to that would be that
you would have to declare a named type as the enumeration type and return
that, or use the non-generic IEnumerable and reflection to get the actual
properties out of the returned enumerated objects.

If that doesn't help answer your question, you should consider writing
your question in a more specific, more detailed way, including a
concise-but-complete code sample that clearly illustrates exactly what
you're trying to do.

Pete
 
D

David

Hi Peter,

This is about as concise as I can get. All other code around it is just
fluff. What I didn't want to do is to make a verbose message and you fall
asleep half way through.

Let me add a sample of the actual XML that I am using...


For the xq, I am using...

<?xml version="1.0" encoding="UTF-8"?>
<form name="MEFS 106" application-name="MEFS 106">
<submit id-dashed="AJX-AAE-B5Q-J4" email="myemail@myemailcom"
phone="+441234567890"/>
<field type="checkbox" name="p1_additional_audit">false</field>
<field type="textfield" name="p1_sealing_plier_no" normalized-score="1"
resemblance-score="1">abc123</field>
<field type="textfield" name="p1_date_of_audit" normalized-score="1"
resemblance-score="1">12/03/2008</field>
<field type="textfield" name="p1_manual_no" normalized-score="1"
resemblance-score="1"></field>
</form>



For the xmap, I am using...

<?xml version="1.0" encoding="utf-8" ?>
<application id="MEFS106">
<database DBName="Audit" TableName="MFS10" />
<mapping DBField="Email" XMLField="submit:email" />
<mapping DBField="Phone" XMLField="submit:phone" />
<mapping DBField="Additional_Audit" XMLField="p1_additional_audit" />
<mapping DBField="Sealing_Plier_No" XMLField="p1_sealing_plier_no" />
<mapping DBField="Date_of_Audit" XMLField="p1_date_of_audit" />
<mapping DBField="Manual_No" XMLField="p1_manual_no" />
</application>



So, xmap reads the xml above (application). It loops through the mapping
fields. For the email, it picks out "submit:email". The left side is to tell
me it is not in a xq 'field' but in the zq 'submit' field.

xmap then loops through the mapping rows. It picks out in this example,
Additional_Audit, which has an XMLField attribute of p1_additional_audit.

So, the xmap describes the xq and which field I want the value from,
xmap.XMLField = 'p1_additional_audit' tells me that I want the value 'false'
from xq.p1_additional_audit and that xmap.XMLField = 'submit:email' tells me
that I want the value '(e-mail address removed)' from the xq.submit.email. (Note,
only items with : get their values from the attributes.)

The problem area I appear to have is...

if (mapItem.XMLField.Contains(":"))
{
string[] xField = mapItem.XMLField.Split(':');
fieldValue.Append("'" + xq.Select(d =>
xField[1]) + "'");
}

I don't yet fully understand the .Select() part and how to use it to get
what I want.

Does this help make it any clearer. My apologies for missing stuff out. I
don't know what else I can add.

--
Best regards,
Dave Colliver.
http://www.AshfieldFOCUS.com
~~
http://www.FOCUSPortals.com - Local franchises available


Peter Duniho said:
Hi Peter,

Let me start again...

As I wrote, you should post a concise-but-complete code example that
reliably demonstrates what you're trying to do.
[...]
foreach (var mapItem in xmap.First().Mappings)
{

if (mapItem.XMLField.Contains(":"))
{
string[] xField =
mapItem.XMLField.Split(':');
fieldValue.Append("'" + xq.Select(d =>
xField[1]) + "'");
}
else
{
fieldValue.Append("'" +
xq.First().Fields.Where(a => a.Name == mapItem.XMLField).First() + "'");
}
}

In my foreach loop, I am trying to append to fieldValue. The value in
xField
will be something like... form:email, (this is from the xmap query).
Now,
What I need to do is to get the value held in the Value field from the xq
query. Basically, the xq query holds all the values. The xmap query
defines
where in the xq query to get my value. So, for example... I need to get
the
value " me@myemailcom " from the row which has the Name = "email". The
text
in Name is what I am putting into the fieldValue.Append.

I still don't really understand what the problem is.

In the code you posted, the case that appears to be the
"default"/"nameless"/whatever case seems to have the kind of code you
need. In particular, you get the first generated "form" query result
(presumably that's used as the default), and then query the fields for the
one that matches the name of the field of interest, and then finally you
take the first result (presumably the normal situation is for there to be
only one result).

For the qualified scenario (i.e. instead of just "email", you have
"formName:email") you can just use a similar technique for your "xq"
enumeration, adding a ".Where(a => a.Name == xField[0])" between the "xq"
and ".First()", to ensure you're selecting from the correct "form" element
of the original data.

But, as I said, because you haven't posted a concise-but-complete code
example, I may still yet misunderstand the question. You really should
post an actual concise-but-complete code sample. Otherwise, you'll just
get random stabs in the dark, which may or may not be helpful.

Pete
 
P

Pavel Minaev

The problem area I appear to have is...

                         if (mapItem.XMLField.Contains(":"))
                         {
                             string[] xField =  mapItem.XMLField.Split(':');
                             fieldValue.Append("'" + xq.Select(d =>
xField[1]) + "'");
                         }

I don't yet fully understand the .Select() part and how to use it to get what I want.

Just follow Peter's advice from his last reply to you:

"For the qualified scenario (i.e. instead of just "email", you have
"formName:email") you can just use a similar technique for your "xq"
enumeration, adding a ".Where(a => a.Name == xField[0])" between the
"xq" and ".First()", to ensure you're selecting from the correct
"form" element of the original data."
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

How do I do this in Linq 3
Linq 3
Linq to SQL Grouping 2
Looping through Linq fields 5
linq and gridview sorting 2
Linq without DBML 2
Long time with assigning linq values 2
Linq problem 7

Top