Frage

I have been battling with the following problem. I have a DataReader class which is simplified below:

public class DataReader
{
    public string SchemeName { get; set; }        
}

Then I have a Map class which inherits a Map method.

public class DataReaderMap: CsvClassMap<DataReader>
{
   ...
   private void MapPropertyToColumnHeader()
   {
     // do the mapping of column headers in the csv file to the property name on the 
     // DataReader class.

     //This is what I would do in a simple case.
     this.Map(DataReader => DataReader.SchemeName).Name("SName");  
   }
}

My problem is to correctly replace the line

this.Map(DataReader => DataReader.SchemeName).Name("SName");  

With something a bit more flexible in my specific case such as

// This code might be wrong but it is as far as I managed to get!
var par = Expression.Parameter(typeof(DataReader));
var memberExpression = Expression.Property(par, "SchemeName");

// lambaExpression is a LambdaExpression not Expression<Func<DataReader, object>>
// THIS LINE DOES NOT COMPILE OF COURSE!
var lambaExpression = Expression.Lambda(memberExpression, par);

var comp = lambaExpression.Compile();  // this is no useful, is it?

// kvPair.Value is "SName" and is read off a mapping file I use
this.Map(lambaExpression).Name(kvPair.Value);

I have more or less understood what Lamba Expressions are and how expression trees can be used but I am not in any way proficient at applying them yet.

The problem here is that I am not sure how to provide the Map method with a lambaExpression of type

Expression<Func<DataReader, obj>>

as expected.

When I debug I see that lambaExpression shows as

lambaExpression
{Param_0 => Param_0.SchemeName}
Body: {Param_0.SchemeName}
CanReduce: false
DebugView: ".Lambda #Lambda1<System.Func`2[csvReaderConsole.Readers.DataReader,System.String]>    (csvReaderConsole.Readers.DataReader $var1)\r\n{\r\n    $var1.SchemeName\r\n}"
Name: null
NodeType: Lambda
Parameters: Count = 1
ReturnType: {Name = "String" FullName = "System.String"}
TailCall: false
Type: {Name = "Func`2" FullName = "System.Func`2[[csvReaderConsole.Readers.DataReader,        csvReaderConsole, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}

but I still fail to understand how I may use this to poduce the equivalent expression to

DataReader => DataReader.SchemeName

which I would normally use.

War es hilfreich?

Lösung

Assuming that Map function has signature string Map(Expression<Func<DataReader, object>> expr) you just need to change your lambda expression like that:

var lambaExpression = Expression.Lambda<Func<DataReader, object>>(memberExpression, par);

There is no need to compile it, unless Map accepts Func<DataReader, object> and not Expression.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top