jjf1978
jjf1978

Reputation: 199

Query by string name?

Is there a way to query the Entity Framework by the string name of the entity? Currently, I am achieving this by implementing a WCF OData service using Entity Framework. I build the URI and execute it against the DbContext (see my current implementation below). This works for simple entities, but any complex entity with a lot of navigation properties and thousands of records crashes the IIS Worker Process with an Out Of Memory Exception.

Current implementation:

public static IEnumerable<object> GetList(string entityName)
{
    Uri dataAccessURI = New Uri(string.Format("https://MyServer/Service.svc/{0}", entityName))
    result = DbContext.Execute<object>(dataAccessURI , "GET", true);

    return result;
}

I am able to accomplish a save just by entity name, what about querying?

db.AddObject(entityName, record);
db.SaveChanges();

Note: I cannot use Generics. I'd love to be able to use something like

public static DbSet<TEntity> GetList<TEntity>()

but I cannot because the application is only passed the string name of the entity.

Upvotes: 1

Views: 1129

Answers (2)

smoksnes
smoksnes

Reputation: 10851

DbContext can create a DbSet based on a provided type. And a type can be created from a string. So if you know the name of the entity you should be able to do something like this:

public static IEnumerable<object> GetList(string entityName)
{
    Type entityType = Type.GetType(string.format("Namespace.{0}, MyAssembly", entityName);
    DbSet dbSet = DbContext.Set(entityType);

    // DbSet implements IEnumerable, so you will be able to safely cast it like so.
    // Or you can assign it to IEnumerable directly.

    IEnumerable list = dbSet as IEnumerable;
    return list.Cast<object>.ToList();
}

It's not the prettiest solution. But it works. I do not know about the performance impact.

It has the obvious downside that you need to know the namespace of the entity. But as long as all your entities are in the same namespace, such as DataAccess.Models or DataAccess.Entitites, it should work.

Also note that this will query the entire table and fetch all rows. This may, or may not, be what you want. You might also want to dispose the DbContext somewhere.

Upvotes: 2

Saeid
Saeid

Reputation: 1663

You can write your own queries using the following convension in EF:

using (var context = new BloggingContext()) 
{ 
    var blogNames = context.Database.SqlQuery<string>( 
                       "SELECT Name FROM dbo.Blogs").ToList(); 
}

But what I strongly suggest you is to use Dapper if you want to generate dynamic queries. It does something similar, but much faster. You can read more about dapper here.

Upvotes: 1

Related Questions