1

I was found following code to find out the table name of an entity given entity class type using GetTableName method. But GetEntitySet method fails, because in TPH the table name, and therefore seemingly EntitySetBase is different than the subtype. It throws an exception with message "Entity type not found in GetTableName", from the throw statement in line 15.

If I have a base class A and a derived class B, how can I find out which EntitySetBase object does type B correspond to? (It should give me EntitySetBase related to A, so that I can find out records are in table [dbo].[As].)

    private static Dictionary<Type, EntitySetBase> _mappingCache =
       new Dictionary<Type, EntitySetBase>();

    private EntitySetBase GetEntitySet(Type type) {
        if (!_mappingCache.ContainsKey(type)) {
            ObjectContext octx = ((IObjectContextAdapter) this).ObjectContext;
            string typeName = ObjectContext.GetObjectType(type).Name;
            var es = octx.MetadataWorkspace
                            .GetItemCollection(DataSpace.SSpace)
                            .GetItems<EntityContainer>()
                            .SelectMany(c => c.BaseEntitySets
                                            .Where(e => e.Name == typeName))
                            .FirstOrDefault();
            if (es == null)
                throw new ArgumentException("Entity type not found in GetTableName", typeName);
            _mappingCache.Add(type, es);
        }
        return _mappingCache[type];
    }

    private string GetTableName(Type type) {
        EntitySetBase es = GetEntitySet(type);
        return string.Format("[{0}].[{1}]",
            es.MetadataProperties["Schema"].Value,
            es.MetadataProperties["Table"].Value);
    }
ciuncan
  • 1,062
  • 2
  • 11
  • 25
  • Check the answer here: http://stackoverflow.com/a/18964974/150342 – Colin Apr 28 '14 at 09:35
  • Yes, actually the above code is from your answer and a related blog post. But the problem here is, it does not work when you provide a type that is down in a hierarchy which is mapped as TPH. It cannot find related `EntitySetBase` object because there is none for class `B`, but only for `A`. – ciuncan Apr 28 '14 at 09:39
  • I also found this library https://entityframework.codeplex.com/documentation, which looked promising and a neat solution. `ctx.Db(entryEntityType).TableName` But it gave me an error for any call of `Db` extension method (with or without parameters/generic type parameters) and the error message was exactly containing the type `B`. So I thought maybe this special case was not considered in that library. – ciuncan Apr 28 '14 at 09:43
  • 1
    Did you look at the other links in that answer? http://romiller.com/2013/09/24/ef-code-first-mapping-between-types-tables/ and http://romiller.com/2014/04/08/ef6-1-mapping-between-types-tables/ – Colin Apr 28 '14 at 09:49
  • To put it more specifically, when you watch the result of this expression `var es = octx.MetadataWorkspace.GetItemCollection(DataSpace.SSpace).GetItems().SelectMany(c => c.BaseEntitySets.Select(e => e.Name))`, you observe that none of them are derived types, only base types exist there. I cannot find any information related to mapping of subtypes to a table name or to a `BaseEntitySet` object. – ciuncan Apr 28 '14 at 09:53
  • I am now looking into them. Hovewer, I am currently using EF6, but soon will need downgrade to 5 due to lack of support for Oracle (gonna switch to Oracle 10g from Sql Server 2012). – ciuncan Apr 28 '14 at 09:56
  • Although there is no inheritance in http://romiller.com/2014/04/08/ef6-1-mapping-between-types-tables/ it seems it might work. Again there is the wall of EF6. :-/ – ciuncan Apr 28 '14 at 10:02

0 Answers0