如何根据表名在DbContext中选择正确的DbSet

时间:2014-10-10 18:24:19

标签: c# linq entity-framework reflection

假设我有一个带有以下DbSets的DbContext

class Amimals : DbContext
{
    public DbSet<Dog> Dogs { get; set; }
    public DbSet<Cat> Cats { get; set; }
}

每个EntityTypeConfiguration内部我为每个DbSet定义表,如

class DogConfig : EntityTypeConfiguration
{
    public  DogConfig()
    {
        this.ToTable("DOG_TABLE");
        ...
    }
}

现在,如果我有表名和DbContext,我怎样才能获取并使用正确的DbSet?

void foo()
{
    string tableName = this.GetTableName();
    using(Animals context = new Animals())
    {
        /* Made up solution */
        DbSet animalContext = context.Where(c => c.TableName == tableName);
        ...
        /* Do something with DbSet */
        ...
    }
}

3 个答案:

答案 0 :(得分:14)

您可以使用方法Type通过DbContext.Set(Type entityType)从DbContext获取DbSet。因此,如果您将模型类名称作为字符串,则应该映射到实际的clr类型。

例如:

string tableName = "Cat";
var type = Assembly.GetExecutingAssembly()
        .GetTypes()
        .FirstOrDefault(t => t.Name == tableName);

if(type != null)
    DbSet catContext = context.Set(type);

你也可以使用Full Assembly Qualified Name Type.GetType(&#39; ...&#39;)

从字符串中获取类型

如果您可以通过某种方式以通用方式存储配置并使用通用context.Set<T>()方法,那将更加容易。

答案 1 :(得分:1)

另一种方法如下,对我来说很好:

Type t = Type.GetType(Assembly.GetExecutingAssembly().GetName().Name + "." + "TableName");
DbSet dbset = dbcontext.Set(t);

答案 2 :(得分:0)

在 DotNetCore 中,我做了类似的事情。在这种情况下,最好使用白名单来确保某人不会请求不受欢迎的实体。

    [HttpGet]
    [Route("entities/{entityName}")]
    public IActionResult GetEntities(string entityName)
    {
        var name = Assembly.GetExecutingAssembly().GetName().Name + ".path.to.your.entity." + entityName;
        Type entityType = Type.GetType(name);
        var results = _myContext
            .GetType()
            .GetMethod("Set")
            .MakeGenericMethod(entityType)
            .Invoke(_myContext, null);
        return Ok(results);
    }