0

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);
Benji
  • 615
  • 5
  • 11
  • 25

1 Answers1

1

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

Community
  • 1
  • 1
grek40
  • 13,113
  • 1
  • 24
  • 50
  • This does exactly what I wanted and I don't see a scenario where there would be more than one `DisplayName`. Very good and elaborate answer – Benji Oct 26 '16 at 14:47
  • Worth noting as well with the code from the edited answer the `DefaultIfEmpty` should be changed to `DefaultIfEmpty(entity.Entity.GetType().Name)` otherwise it will `name` will be `DbEntityEntry` when no `DisplayName` is specified – Benji Oct 26 '16 at 15:07
  • I can edit `entity` into `change.Entity`, thought it would be obvious that `entity` represents this in the answer. – grek40 Oct 26 '16 at 15:12
  • Yes ofc, that's not what I tried to point out. Before you edited your answer `DefaultIfEmpty(type.Name)` returns the name of the class but using the edited answer `DefaultIfEmpty(type.Name)` returns `DbEntityEntry` – Benji Oct 26 '16 at 15:16