neel shah
neel shah

Reputation: 2271

Dynamically selecting table using entity framework

I have a property name for different entities like car,person etc.Depending on the Id I want to get the name.But I would like to get it in done in a single method which takes entityName and gives the output depending on that. Something like this:

public string GetEntityByName(int id,string entityName)
    {
        using (var context = new MyContext())
        {
            return context[entityName].Find(id).Name;
        }
    }

Upvotes: 5

Views: 2336

Answers (2)

mr100
mr100

Reputation: 4428

How about using generic method that indicates entity not by name but by type instead? The result you may store as dynamic variable so that you will be able to access any property in it.

public string GetEntityByName<TEntity>(int id)
{
    using (var context = new MyContext())
    {
        dynamic entity = context.Set<TEntity>.Find(id);
        try
        {
            return entity.Name;
        }
        catch(Exception e)
        {
            // Handle the situation when requested entity does not have Name property
        }
    }
}

Alternatively you may use reflection to access Name property:

public string GetEntityByName<TEntity>(int id)
{
    var nameProperty = typeof(TEntity).GetProperty("Name");
    if(nameProperty == null)
        return null;
    using (var context = new MyContext())
    {
        object entity = context.Set<TEntity>.Find(id);
        return nameProperty.GetValue(entity) as string;
    }
}

The above methods you may use like that:

 string name = GetEntityByName<Car>(id);

If you insist on having the entity type passed as string parameter you may achieve it as well:

public string GetEntityByName(int id, string entityName)
{
    Type entityType = Type.GetType(entityName);
    var nameProperty = entityType.GetProperty("Name");
    if(nameProperty == null)
        return null;
    using (var context = new MyContext())
    {
        object entity = context.Set(entityType).Find(id);
        return nameProperty.GetValue(entity) as string;
    }
}

The above works only if GetEntityByName method is defined in the same assembly and the same namespace as entity classes. Otherwise as parametr to GetType method you have to pass full type name.

Upvotes: 2

Matias Cicero
Matias Cicero

Reputation: 26281

All your entities should extend a base class or implement an interface that defines a Name property.

public interface INamed {
     string Name { get; set; }
}

public class Car : INamed {
     public int Id { get; set; }
     public string Name { get; set; }
}

I'm not aware if DbContext supports indexed properties, but if it does, you may manage to do something like this:

INamed namedEntity = context[entityName].Find(id) as INamed;
if(namedEntity != null)
     return namedEntity.Name;
else
     return string.Empty;

If you're sure that all your entities are INamed, then you can achieve it all in one line:

return ((INamed)context[entityName].Find(id)).Name;

Please note that the latter approach will rise or throw an exception if the retrieved entity is not implementing INamed

Upvotes: 2

Related Questions