Domanda

How to get single column with anonymous method using linq expression. Here's my code and it doesn't work:

public IEnumerable<object> GetPropertyValues<T>(string propName) where T : class
{
    return base.Query<T>().AsEnumerable()
        .Where(x => x.GetType().GetProperty(propName).Name == propName)
        .Select(x => x.GetType().GetProperty(propName).GetValue(x, null));
}

Here's the code in non generic method:

base.Query<Product>().Select(x => x.ProductName).AsEnumerable();

Thanks in advance.

È stato utile?

Soluzione

This condition is incorrect, because when the property propName is missing, it crashes, rather than returning false:

.Where(x => x.GetType().GetProperty(propName).Name == propName)

If you wanted to say "the dynamic type has the property propName", a proper condition for it would look like this:

.Where(x => x.GetType().GetProperty(propName) != null)

Note that this is necessary only when some, but not all, subclasses of T have the desired property propName. If the property is present in the T itself, you could get property upfront, and do the rest of the query like this:

var theProp = typeof(T)..GetProperty(propName);
return base.Query<T>().AsEnumerable().Select(x => theProp.GetValue(x, null));

Altri suggerimenti

Once you call AsEnumerable() all further filtering will happen in memory rather than SQL. Thus, you could do:

var prop = typeof(T).GetProperty(propName);
return base.Query<T>().AsEnumerable().Select(t => prop.GetValue(t));

but this will select all columns of T into memory before filtering down to just one. To do the filtering in SQL, you'll need to dynamically construct an expression:

var prop = typeof(T).GetProperty(propName);
var parameter = Expression.Parameter(typeof(T));
var memberAccess = Expression.MakeMemberAccess(parameter, prop);
var selector = Expression.Lambda<Func<T, TProperty>>(memberAccess, parameter);
return base.Query<T>().Select(selector);

For an enumeration of any type of objects...

public static IEnumerable<Object> Pluck<Object>(this IEnumerable<Object> source, string propName)
{
    return source
        .Select(x => new {
            obj: x
            prop: x.GetType().GetProperty(propName)
        })
        .Where(x => x.prop != null)
        .Select(x => x.prop.GetValue(x.obj));
};

For an enumeration of a single type of object...

public static IEnumerable<Object> Pluck<T>(this IEnumerable<T> source, string, propName)
{
    var prop = typeof(T).GetProperty(propName);
    return prop == null
         ? Enumerable.Empty<Object>()
         : source.Select(x => prop.GetValue(x));
};
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top