4

Trying to create a data access component by mapping fields from an an oracle database to properties on an object. I've created a base object that takes a type and is called like this...

public class Document : DataProviderBase<DataObjects.Document> 
{ 
    // code goes here... 
}

This base object has a method called AddMapping that maps database fields to properties like this...

this.AddMapping<int>("ATD_KEY", "Key")

In this case...

  • int is the type of property
  • ATD_KEY is the field name in the database
  • Key is the property name on DataObjects.Document

The code uses...

typeof(<TParent>).GetProperty(<property name>)

..to get PropertyInfo which is used to get and set the property. While this is great, I would like to add a bit of type safety and lambda expressions to the AddMapping method. I'd like to do something like the following...

this.AddMapping<int>("ATD_KEY", o => o.Key)

..where o is of the type provided by DataProviderBase. This will ensure that property Key is actually of type int and ensures that the string "Key" is not misspelt or the wrong case as is a problem with the current working code shown in the 1st AddMapping method.

Is this possible? if so how?

The closest example I've found is this Dynamic Expression from the Property of the object of the class, however this still refers to the property by string and not by expression.

2
  • It's a bit unclear what are you trying to achieve: could you please clarify your question and any practical merits of expected solution? Thanks and regards, Commented Jun 30, 2014 at 11:47
  • The aim here is type safty. Property names in the previous method are consistantly miss-spelt and cause errors. Does that help? Commented Jul 1, 2014 at 13:50

2 Answers 2

1

You can use something like:

public void AddMapping<T>(fieldName, Expression<Func<TParent, T>> propExpr)
{
    var memberExpr = (MemberExpression)propExpr.Body;
    PropertyInfo property = (PropertyInfo)memberExpr.Member;
    ...
}
Sign up to request clarification or add additional context in comments.

Comments

1

Sure it's possible:

public static PropertyInfo GetProperty<TParent>(Expression<Func<TParent, object>> prop)
{
    var expr = prop.Body;

    if (expr.NodeType == ExpressionType.Convert)
        expr = ((UnaryExpression)expr).Operand;

    if (expr.NodeType == ExpressionType.MemberAccess)
        return ((MemberExpression)expr).Member as PropertyInfo;

    throw new ArgumentException("Invalid lambda", "prop");
}

public void AddMapping<TParent>(fieldName, Expression<Func<TParent, object>> prop)
{
    AddMapping(fieldName, GetProperty(prop).Name);
}

This method has the advantage of requiring only one type parameter (TParent). You pass in a lambda that may contain a cast into the property type. We get rid of that, and then get the member expression.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.