views:

1285

answers:

3

Hi,
I'm looking for an equivalent of the DataContext.GetTable<TEntity> in Entity Framework. I've found the ObjectContext.CreateQuery<T> method but it is different from DataContext.GetTable<TEntity> since it needs a querystring to work.

Is there a way to get an IQueryable object for a table using the entity type without specifying the querystring?

*EDIT: Added code snippet*
This is a snippet of a Repository class I've implemented that works with linq2sql. I can't use ObjectContext.[TableName] because it wouldn't be generic anymore.

public class BaseRepository<TClass> : IDisposable
        where TClass : class
    {
        protected BaseRepository(DataContext database)
        {
            _database = database;
        }
        ...

        public IQueryable<TClass> GetAllEntities()
        {
            IQueryable<TClass> entities = _database.GetTable<TClass>();
            return entities;
        }

        public IQueryable<TClass> GetEntities(Expression<Func<TClass, bool>> condition)
        {  
            IQueryable<TClass> table = _database.GetTable<TClass>();
            return table.Where(condition);    
        }

*EDIT: Added my solution (so far..)*
This is what I'm using:

public IQueryable<TClass> GetEntities(Expression<Func<TClass, bool>> condition)
{  
    IQueryable<TClass> table = _database.CreateQuery<TClass>(typeof(TClass).Name);
    return table.Where(condition);    
}

This works as long as the class name is the same of the table name. This will became a problem for me when I'll start using different objects for the same table.

I hope I've been clear, thanks in advance,
Marco :)

A: 

I hope I'm not missing the point, but wouldn't it be:

ObjectContext.TableName

Where TableName is the EntitySet of the type you want to work with.

TGnat
Hi, I don't want to use the table name because I want to have a generic way of accessing the table.I added a code snippet from my class to better explain what I'd like to achieve.The only solution I can imagine right now is to use the ObjectContext.CreateQuery<T> method changing a bit the structure of my generic class passing to the constructor also the TableName.
crossy
+1  A: 

Actually, the EF designer itself uses CreateQuery with hard-coded strings for the static references. If you dig into the designer file you'll see something like this:

public global::System.Data.Objects.ObjectQuery<Customers> Customers
{
    get
    {
        if ((this._Customers == null))
        {
            this._Customers = base.CreateQuery<Customers>("[Customers]");
        }
        return this._Customers;
    }
}

private global::System.Data.Objects.ObjectQuery<Customers> _Customers;

Technically there's no perfect solution because you can use the same entity type for different entity sets. But you can give it the old college try:

public IQueryable<TEntity> GetEntities<TEntity>()
{
    Type t = typeof(TEntity);
    var edmAttr = (EdmEntityTypeAttribute)Attribute.GetCustomAttribute(t,
        typeof(EdmEntityTypeAttribute), false);
    if (edmAttr == null)  // Fall back to the naive way
    {
        return context.CreateQuery<TEntity>(t.Name);
    }
    var ec = context.MetadataWorkspace.GetEntityContainer(
        context.DefaultContainerName, DataSpace.CSpace);
    var entityType = context.MetadataWorkspace.GetType(edmAttr.Name,
        edmAttr.NamespaceName, DataSpace.CSpace);
    return ec.BaseEntitySets.First(es => es.ElementType == entityType);
}
Aaronaught
Thanks it works fine!By chance today I found a similar solution in the kigg project on codeplex (http://kigg.codeplex.com).
crossy
A: 

it doesn't work. Error: Cannot implicitly convert type 'System.Data.Metadata.Edm.EntitySetBase' to 'System.Linq.IQueryable'.