Benji
Benji

Reputation: 635

Get DisplayName of class from it's DbEntityEntry object

I'm looking to track my modified database entries following this blog post.

I have this class:

[DisplayName("PrettyNameForClass")]
public class UglyClassName
{
...
}

And when I'm saving down the I would like to save down the PrettyNameForClass instead of the ClassName. The code used to get the ClassName

The code I'm currently using:

var modifiedEntities = ChangeTracker.Entries()
        .Where(p => p.State == EntityState.Modified).ToList();

    foreach (var change in modifiedEntities)
    {
        var entityName = change.Entity.GetType().Name;
        var primaryKey = GetPrimaryKeyValue(change);

Upvotes: 0

Views: 1671

Answers (1)

grek40
grek40

Reputation: 13448

The answer is basically, to get the associated attributes by Type.GetCustomAttributes and determine the configured DisplayName.

The following code does this. The second parameter on GetCustomAttributes tells to look into the inheritance hierarchy. Pro: get the attribute even if the entity type is a proxy type; Contra: if the entity type inherits a base class with DisplayNameAttribute set, the result may be unexpected.

var type = entity.GetType();
var name = type.GetCustomAttributes(typeof(DisplayNameAttribute), true)
    .Select(x => ((DisplayNameAttribute)x).DisplayName)
    .DefaultIfEmpty(type.Name)
    .First(); // what if more names are available for some reason?

In short, it's up to you if and how you want to handle the proxy / baseclass problem. Other than that, the solution should work.

Edit in order to avoid the proxy / baseclass problem, you can try

var type = ObjectContext.GetObjectType(entity.GetType());

This should resolve the actual type in case that entity is a proxy type. Then type.GetCustomAttributes(typeof(DisplayNameAttribute), false) can be used to check for the attribute only on the actual type without its base types.

Note, i didn't check this, only took it from this Answer

Upvotes: 1

Related Questions