Gavin Coates
Gavin Coates

Reputation: 1425

Selecting Column Name In Linq By Text

I am working on a website that features a graphing tool, allowing the user to pick up to 3 properties to be displayed on a graph.

I have a database with structure similar to the following:

public class MyClass
{
    public decimal Field1 {get;set;}
    public decimal Field2 {get;set;}
    ...
    public decimal Field10 {get;set;}
}

I need the user to be able to select up to 3 properties, which are then returned in an object.

public class MyResult
{
    public decimal value1 {get;set;}
    public decimal value2 {get;set;}
    public decimal value3 {get;set;}
}

The website contains three dropdowns, with the user picking which of the 10 fields they want to graph as value1,2 or 3.

As a result of this, the value passed into the controller will be a string detailing the column name, however as Linq is strongly typed, the two cannot be interchanged.

How can I write a Linq command that isn't strongly typed, but instead uses the text passed in by the user as the column name?

Something like the following would have been ideal, but doesn't work.

values.Select(x => new MyResult(){ value1 = "Field1", value2 = "Field5", value3 = "Field9"});

Or am I just looking at this the completely wrong way? Is there a better way of achieving this?

Upvotes: 1

Views: 82

Answers (2)

Kien Chu
Kien Chu

Reputation: 4895

It's not LinQ, but you might consider using AutoMapper, it's very convenient in this situation.

Sample:

 Mapper.CreateMap<MyClass, MyResult>()
                .ForMember(dest => dest.Field1, opt => opt.MapFrom(src => src.Value1))
                .ForMember(dest => dest.Field2, opt => opt.MapFrom(src => src.Value2))
                .ForMember(dest => dest.Field3, opt => opt.MapFrom(src => src.Value3))

And later you can call:

MyResult result = Mapper.Map<MyClass>(class);

Upvotes: 2

Hossein Narimani Rad
Hossein Narimani Rad

Reputation: 32481

Using Reflection you can get property values of a class, having their name. Here is the code:

public object GetPropertyOfMyClass(string propertyName, MyClass instance)
{
    System.Reflection.PropertyInfo[] properties = typeof(MyClass).GetProperties();

    return properties.Single(i => i.Name == propertyName).GetValue(instance);
}

Then use it like this:

values.Select(x => new MyResult(){ 
                   value1 =  (decimal)GetPropertyOfMyClass("Field1",x),
                   value2 =  (decimal)GetPropertyOfMyClass("Field5",x),
                   value3 =  (decimal)GetPropertyOfMyClass("Field9".x)});

Upvotes: 1

Related Questions