Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

How to refer to a LINQ field with a variable?

Posted on 2008-10-15
10
Medium Priority
?
1,595 Views
Last Modified: 2013-11-11
I've a LINQ query working fine, then if I want to refer to a returned field from that query in LINQ I use something like:

MyObject.FieldName

And that also works fine.

Now: what I need is a method where I can use:

MyObject.%variable%.

Imagine I want to implement the following:

string GetFieldValue(string MyFieldName)
{
return MyLINQQuery.MyFieldName.ToString(); //where MyLINQQuery is a public LINQ query object and MyFieldName will be a variable specified in the method.
}

How can I do this?
0
Comment
Question by:LMGONCA
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 2
10 Comments
 
LVL 4

Expert Comment

by:novynov
ID: 22721377
Well, the simplest thing that comes to mind relies on you knowing the complete set of field names beforehand. If so, you could just create a switch statement something like code snippet #1 below.

The statements below assume that the return from MyLINQQuery is a MyObject.

It's not exactly a pretty solution, but it would work. The deal is, you are needing to map fieldnames to (compiled) property names. This situation would come up in any similar scenario - not just with using LINQ. I suppose another option would be to use reflection...it would be more flexible...but seems overkill.

Now, regardless of how you do it, there is a bit of an inefficiency here, in that you are retrieving the whole entity/object from the datasource (I assume it's probably a db), and then only selecting one field from it.

That said, you could create a custom query that did a similar switch statement, but did a custom Select() expression based on the field name. This would lower the payload coming back from your datasource - as the only thing returned would be the string.

Let me know if this helps, or if you need more info.

#1
switch(MyFieldName)
{
    case "Field1":
      return MyObject.Field1;
    case "Field2": //An int
      return MyObject.Field2.ToString();
    default:
      return String.Empty;
 
}
 
#2
 
Expression<Func<MyObject,string>> selectExpression = null;
switch(MyFieldName)
{
 
    case "Field1":
      selectExpression = (o => o.Field1);
      break;
   case "Field2":
     selectExpression = (o => o.Field2.ToString());
     break;
    default:
     throw new ApplicationException("Invalid field name.");
     break;
}
 
 
return context.MyObjects.Where(<whatever filter you are using>).Select(selectExpression);

Open in new window

0
 

Author Comment

by:LMGONCA
ID: 22723578
I don't know the field names....if that was the case, I could use the normal properties names.....

MyObject.FieldName = "xxx";

Basically I am calling that method from a dinamically created method...

I need something that abstract the fieldnames.
0
 
LVL 4

Expert Comment

by:novynov
ID: 22724552
Forgive me if I am confused. In your code above, you give an example of something like:

MyObject.FieldName

Doesn't this mean that you know what "MyObject" is, and by extension, what its public properties are?

Can you help me understand?
0
Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

 
LVL 64

Accepted Solution

by:
Fernando Soto earned 2000 total points
ID: 22724734
Hi LMGONCA;

Microsoft has developed a set of extensions called Dynamic LINQ to do what you want to do. The extensions can be downloaded from this MS web site http://msdn.microsoft.com/en-us/vcsharp/bb894665.aspx and I found the original link on this web site, "Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)" http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx.

Once you download the extension you can add the file Dynamic.cs to the project that will use it. and add the following using statement:

using System.Linq.Dynamic;

Then something like the following is possible. I used the Northwind database for this sample.

Fernando

using System.Linq.Dynamic;
 
 
private DataClasses1DataContext nw = new DataClasses1DataContext();
private IEnumerable<Customers> MyLINQQuery;
 
private void Form1_Load(object sender, EventArgs e)
{
    MyLINQQuery = from c in nw.Customers
                  where c.CompanyName == "Bottom-Dollar Markets"
                  select c;
}
 
private void button1_Click(object sender, EventArgs e)
{
    // Get the record for the company Bottom-Dollar Markets and display the field ContactName
    MessageBox.Show(GetFieldValue("ContactName"));
}
 
string GetFieldValue(string MyFieldName)
{
    // Select the single filed in the variable MyFieldName from the query
    var fieldQuery = MyLINQQuery.AsQueryable().Select(MyFieldName);
    // Used to return the value
    String retField = "";
    // Enumerate the single record with the single field returned
    foreach (var f in fieldQuery)
    {
        retField = f.ToString();
    }
    // Return the field value.
    return retField;
}

Open in new window

0
 

Author Comment

by:LMGONCA
ID: 22728649
I have tried your great example, but I am still facing a problem :(

In the line:

public IEnumerable<Entity> MyLINQQuery;

I got the following error:

Compiler Error Message: CS0308: The non-generic type 'System.Collections.IEnumerable' cannot be used with type arguments

I have added:

using System.Linq.Dynamic;
using System.Collections;

Do you know why? Thanks.
0
 

Author Comment

by:LMGONCA
ID: 22728683
I found out why the error was:

I need to use:

using System.Collections.Generic;

Instead of:

using System.Collections;

Working now!

Great - thanks!
0
 

Author Comment

by:LMGONCA
ID: 22728751
Meantime I saw I cannot use any more the MyLINQQuery object the following way:

MyLiNQQuery.Fieldname = "XXX";

Do you know why? Isn't there a way to keep both access methods?.....
0
 
LVL 64

Expert Comment

by:Fernando Soto
ID: 22731275
Hi LMGONCA;


I am glad you got it working. On the other matter about not being able to use this any more:

MyLiNQQuery.Fieldname = "XXX";

I do not see why not can you  post the code so that I can follow the logic.

Fernando
0
 

Author Comment

by:LMGONCA
ID: 22732599
Is quite a big class now, but let's see if I can the involved extracts of it:

public class My_Entity
{

    MyDbDataContext MyDb = new MyDbDataContext();
    public Entity LQEntity = new Entity(); //here now I could change to: public public IEnumerable<Entity> LQEntity....

//lots of code here

string GetFieldValue(string MyFieldName)
{
    // Select the single filed in the variable MyFieldName from the query
    var fieldQuery = LQEntity.AsQueryable().Select(MyFieldName);
    // Used to return the value
    String retField = "";
    // Enumerate the single record with the single field returned
    foreach (var f in fieldQuery)
    {
        retField = f.ToString();
    }
    // Return the field value.
    return retField;
}

}

***************************************************

That was the My_Entity class

Now I consume this class like this:

My_Entity MyEntity = new My_Entity();
MyEntity.LQEntity.Code = MyValue; //here I do access the LQEntity with that object.fieldname method - and I do this in many many places...(and here is great to have the field name appearing automatically to you as you type)

Now in some places I've a datatable with the same field / column structure than the LQEntity entity and to avoid do something like this:

MyTable.Column["ColumnName"] = MyEntity.LQEntity.FieldName;
....dozens of fields....

That's why I want that possibility to use the LQEntity as a variable name, something like:

for each (DataColumn MyCol in MyTable.Columns)
{
MyCol[MyCol.ColumnName] = MyEntity.GetFieldValue(MyCol.ColumnName);
}

Got it? :)
0
 
LVL 64

Expert Comment

by:Fernando Soto
ID: 22734671
Hi LMGONCA;

Looking at this statement, MyLiNQQuery.Fieldname, If Fieldname is the string value that holds the name of the column you wish to modify then that will not work. About the only way to make something like that is to us Reflections, this is a subject I am not too well versed on.

Fernando
0

Featured Post

NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The object model of .Net can be overwhelming at times – so overwhelming that quite trivial tasks often take hours of research. In this case, the task at hand was to populate the datagrid from SQL Server database in Visual Studio 2008 Windows applica…
This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…

721 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question