c# - 从类型中获取 DbSet

标签 c# entity-framework asp.net-core asp.net-core-mvc entity-framework-core

我正在尝试为 MVC 6 应用程序制作通用表查看器/编辑器。

我目前正在使用

Context.GetEntityTypes();

向我返回表格列表。

现在我需要获取特定类型的数据。我当前的实现是:

// On my context
public IQueryable<dynamic> GetDbSetByType(string fullname)
{
    Type targetType = Type.GetType(fullname);

    var model = GetType()
        .GetRuntimeProperties()
        .Where(o =>
            o.PropertyType.IsGenericType &&
            o.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>) &&
            o.PropertyType.GenericTypeArguments.Contains(targetType))
        .FirstOrDefault();

    if (null != model)
    {
        return (IQueryable<dynamic>)model.GetValue(this);
    }

    return null;
}

在我的 Controller 中使用此代码

[HttpGet("{requestedContext}/{requestedTable}/data")]
public IActionResult GetTableData(string requestedContext, string requestedTable)
{
    var data = Request.Query;
    var context = GetContext(requestedContext);

    if (context == null)
    {
        return new ErrorObjectResult("Invalid context specified");
    }
    var entity = context.GetEntity(requestedTable);

    if (entity == null)
    {
        return new ErrorObjectResult("Invalid table specified");
    }

    var set = context.GetDbSetByType(entity.ClrType.AssemblyQualifiedName);

    if (set == null)
    {
        return new ErrorObjectResult("Invalid table specified - DbSet could not be found");
    }

    var start = Convert.ToInt32(data["start"].ToString());
    var count = Convert.ToInt32(data["length"].ToString());
    var search = data["search[value]"];

    return new ObjectResult(set.Skip(start).Take(count));
}

实际上,这将返回长度为 count 的数据从位置 start .但是我无法对 IQueryable<dynamic> 的特定属性执行查询.

问题是:

  1. 这似乎是一件微不足道的事情,所以我几乎可以肯定我遗漏了什么 - 这一定很容易做到。
  2. 如果不是 1,那么我将如何转换我的 object set回到DbSet<T>这样我就可以执行我的查询了吗?如果我设置一个断点并进行检查,我可以看到我所有的数据就在那里。

注意:这是 EF7

附加信息:

  1. requestedTable是完全合格的类型 EG:<mysystem>.Models.Shared.Users

编辑(2016/5/5)

我最终只是用纯 SQL 完成了所有工作 - 如果有人设法让这个工作正常,请告诉我!

最佳答案

使用通用方法并使用 DbContext.Set<TEntity>() 会更简单.您可以像这样在运行时创建通用方法:

public IActionResult GetTableData(string requestedContext, string requestedTable)
{
    var context = GetContext(requestedContext);

    if (context == null)
    {
        return new ErrorObjectResult("Invalid context specified");
    }
    var entity = context.GetEntity(requestedTable);

    if (entity == null)
    {
        return new ErrorObjectResult("Invalid table specified");
    }

    var boundMethod = s_getTableDataMethodInfo.MakeGenericMethod(entity.ClrType);
    return boundMethod.Invoke(this, new object[] { context }) as IActionResult;
}

private static readonly MethodInfo s_getTableDataMethodInfo
    = typeof(MyController).GetTypeInfo().GetDeclaredMethod("GetTableDataForEntity");

private IActionResult GetTableDataForEntity<TEntity>(DbContext context)
    where TEntity : class
{
    var data = Request.Query;
    var start = Convert.ToInt32(data["start"].ToString());
    var count = Convert.ToInt32(data["length"].ToString());
    var search = data["search[value]"];

    return new ObjectResult(context.Set<TEntity>().Skip(start).Take(count));
}

关于c# - 从类型中获取 DbSet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34259504/

相关文章:

.net - 如何将 'Tags' 添加到我的简单博客文章类库和存储库中?

c# - Entity Framework - 重用复杂类型

asp.net-mvc - ASP.NET Core 将路由映射到静态文件处理程序

c# - MVC 4 异常处理程序属性调用顺序

C# 在设计器中显示可浏览的子属性

javascript - 强制浏览器使用特定分辨率

c# - 在 Azure 中使用 SendGrid 创建 Outlook 日历邀请(C#、.NET)

entity-framework - 如何向 ADO.NET 实体添加约束?

c# - Asp.net Core MVC 属性路由约束的意外行为

c# - 在类库中执行asp.net core EF迁移,无需硬编码连接字符串