Rayet
Rayet

Reputation: 298

Generic reflection, how to get a list?

I have the following piece of code:

var prop = FindEntityProperty(entityName);

if(prop==null)
{
    throw new InvalidOperationException("entityName: " + entityName);
}

var db = new DatabaseContext();
Type returnType = prop.PropertyType;

var col = (prop.GetValue(db) as ???);
Data = col.ToList(); //or something IEnumerable<?>

Situation looks that, I have PropertyInfo named prop here). I'm sure this property is DbSet<Τ>. I don't know what type is T (only that it's a class). But because it's generic DbSet, it can be treated like a generic IEnumarble. So, because propertyInfo.GetValue() return a simple object, Ι need to cast my collection.

How can I do this?

I know it's a bad practice in programming. Here I'm doing it only for learning reflection.

Upvotes: 1

Views: 155

Answers (1)

Jeffrey H.
Jeffrey H.

Reputation: 36

I've had a similar problem like that, i wanted to create a method that gives me the object back from the database, so created this piece of code. I hope this helps you:

Put this into your DatabaseContainer:

public IEnumerable<TEntity> Find<TEntity>(Dictionary<string, object> findValues = null) where TEntity : EntityObject
    {
        var entities = this.CreateObjectSet<TEntity>().ToList();

        if (findValues!= null && findValues.Count > 0)
        {
            foreach (var item in findValues)
            {
                if(item.Value != null)
                    entities = entities.DynamicContains<TEntity>(item.Key, item.Value);
            }
        }

        return entities;
    }

And put this into a extention class:

public static List<TEntity> DynamicContains<TEntity>(this IEnumerable<TEntity> entities, string propertyName, object item)
    {
        List<TEntity> comparingEntities = new List<TEntity>();
        foreach (var obj in entities)
        {
            var property = obj.GetType().GetProperty(propertyName);
            if (property.PropertyType == typeof(String) && ((string)property.GetValue(obj, new object[] { })).ToLower().Contains(item.ToString().ToLower()))
                comparingEntities.Add(obj);

            if (property.PropertyType == typeof(Boolean) && ((bool)property.GetValue(obj, new object[] { })) == (bool)item)
                comparingEntities.Add(obj);     
        }

        return comparingEntities;
    }

Usage:

Dictionary<string, object> findValues = new Dictionary<string, object>();
findValues.Add("Name", "Tom");
findValues.Add("Age", 4);

var list1 = db.Find<Person>(findValues); // Returns a list of persons that includes the find values.
var list2 = db.Find<Person>() // Returns all persons in the database.

Upvotes: 2

Related Questions