Search code examples
c#entity-frameworkef-code-firsttable-per-type

EF MappingApi returns column name for parent class


I'm building a generic method which must insert alot of data. So I'm using SqlBulkCopy for insertion, reflection to get values from objects and MappingApi to get DB schema. I don't need to insert nested objects in order to keep it as simple as possible.

I'm trying to get table name like this:

using (var ctx = GetStorage())
{
    tableName = ctx.Db(typeof(T)).TableName;
}

It's working for base classes but not for derived classes.

Schema:

public abstract class A
{
    public int Id { get; set; }
}

public class B: A
{
    public int Site_Id { get; set; }
}

public class AMap : EntityTypeConfiguration<A>
{
    public AMap()
    {
        HasKey(t => t.Id);
        Property(t => t.Id).IsRequired();

        ToTable("A");
        Property(t => t.Id).HasColumnName("Id");
    }
}

public class BMap : EntityTypeConfiguration<B>
{
    public BMap()
    {
        HasKey(t => t.Id);
        Property(t => t.Id).IsRequired();
        Property(t => t.Site_Id).IsRequired();

        ToTable("B");
        Property(t => t.Id).HasColumnName("Id");
        Property(t => t.Site_Id).HasColumnName("Site_Id");
    }
}

EF CRUD operations are working on this schema. EF is sending two requests per each operation first for class B and then for class A. But, ctx.Db(typeof(B)).TableName == "A"

Any ideas on how to get throw this and get right table name for class?


Solution

  • If you can use attribute instead ToTable("B"), here is a simple solution

    public static string GetTableName<T>()
            {
                var attr = Attribute.GetCustomAttributes(typeof (T), typeof (TableAttribute)).OfType<TableAttribute>().FirstOrDefault();
    
                if (attr != null)
                {
                    return attr.Name;
                }
    
                throw new Exception("Could not load TableAttribute of type" + typeof (T).Name);
            }