Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get all names of properties in an Entity?


What I'm trying to do is to pass an entity object to method and return all the names of the properties in it.
I'm using this code to get all the props names :

return classObject.GetType().GetProperties();

The problem is that this code return "EntityKey" and "EntityState" as properties whe I use it with Entity Object.
Is there any way to do it ?

Thanx in advance

like image 746
Dabbas Avatar asked May 01 '11 20:05

Dabbas


3 Answers

It is also possible without reflection:

using (var context = new ModelContainer())
{
    // Access CSDL
    var container = context.MetadataWorkspace
                           .GetEntityContainer(context.DefaultContainerName, DataSpace.CSpace);
    // Access name of related set exposed on your context
    var set = container.BaseEntitySets[context.YourEntitySet.EntitySet.Name];
    // Access all properties
    var properties = set.ElementType.Members.Select(m => m.Name).ToList();
    // Access only keys
    var keys = set.ElementType.KeyMembers.Select(m => m.Name).ToList();
}

As you can see you have access to much more then names. The example shows that you can now which property is part of key. If you access Members directly you can know which property is scalar, complex type or navigation property.

All information are already loaded so there is no need for reflection. If you want to use reflection don't forget to use it only once (first time you need it) and then store and reuse received property names. Reflection is slow so using it each time you need names is a bad practice.

like image 95
Ladislav Mrnka Avatar answered Nov 03 '22 22:11

Ladislav Mrnka


You want all direct properties, but not the properties of the base type, which in your case is EntityObject:

var type = classObject.GetType();
//alternatively call out directly: typeof(EntityObject).GetProperties()...
var basePropertyNames = type.BaseType.GetProperties().Select(x => x.Name);
var props = type.GetProperties().Where(p => !basePropertyNames.Contains(p.Name));

This sample assumes there is a base type (which is the case for DB first), refactor when that is not guaranteed.

Edit from @Matt's comment: All of the above is unnecessary, could slap my head for not thinking of this - just use the right binding flags:

return classObject.GetType().GetProperties(BindingFlags.DeclaredOnly | 
                                           BindingFlags.Public | 
                                           BindingFlags.Instance);
like image 23
BrokenGlass Avatar answered Nov 03 '22 22:11

BrokenGlass


I had the same problem. The solution I found was to create an array with the name of the properties to return (I olnly need a few). In your case, since it can be laborious to keep track of all properties, I would filter the properties EntityKey and EntityState and return all the others. The code would be something like this:

public IEnumerable<PropertyInfo> GetProperties()
{
    Type t = this.GetType();

    return t.GetProperties()
        .Where(p => (p.Name != "EntityKey" && p.Name != "EntityState"))
        .Select(p => p).ToList();
}

Don't know if there is a better solution, but it would be nice ;) Hope it helps!

like image 2
jmpcm Avatar answered Nov 03 '22 21:11

jmpcm