【问题标题】:Get record from DB using reflection and generic type使用反射和泛型从数据库获取记录
【发布时间】:2019-03-05 23:23:16
【问题描述】:

我想从数据库中检索一个实例。我已经使用 EF 创建了一个数据库模型。我可以使用静态方式:

var tempRecord= db.Table1.First(a => a.column1 ==  columnValue);

但是,如果当前表的类发生变化,有时是 Table1,有时是 Table2,怎么办? 我试过这样的东西,但显然它不起作用:

Type entityType = Type.GetType(currentTable);
var tempRecord2 = db.entityType.First(a => a.column1 == columnValue);

编辑:currentTable 是一个字符串

有 5 个表,每个表需要签出不同的列。所以我会为每个表检查列的列表

【问题讨论】:

  • 您可以使用db.currentTable.First(a => a.column1 == columnValue)。你试过这个吗?
  • currentTable 是一个字符串
  • 只有两个表还是可能更多?如果只有两个表,只需查询它们并检查实体是否为空:-)
  • 有5个表,每个表需要不同的列进行签出。所以我会为每个表检查列的列表。
  • 您是否尝试过使用where T : YourEntityTypeClass 设置通用方法?问题是每个对象都需要有一个column1 列..

标签: c# sql-server entity-framework


【解决方案1】:

我建议看看this 的答案,如果它能给你灵感。

在其中,代码依赖于泛型函数,传递一个 LINQ Func<> 来委托 First()(或者在他的情况下是 SingleOrDefault()),因此它可以对任何 ObjectSet(或表)执行相同的方法发送到方法,如下所示:

 public T Single<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T:class {
        return GetObjectSet<T>().SingleOrDefault(expression);
    }

到目前为止一切顺利。但是这样一来,您的列就必须全部命名为column1。但建议是检索主键,链接答案中也对此进行了进一步说明。

【讨论】:

    【解决方案2】:

    假设“column1”是一个公共属性,你可以使用这个方法:

            Type type = Type.GetType(currentTable);
            IEnumerable a = db.Database.SqlQuery(type, "SELECT * FROM " + name + " WHERE column1 = " + "x");
    

    然后,根据数据库修改查询并获取第一行,或者在运行时强制转换并使用 First()。

    【讨论】:

      【解决方案3】:

      这可能会有所帮助:

          Type entityType = Type.GetType("MyNameSpace.Models.City");
          var result = ((IQueryable<object>)db.Set(entityType)).FirstOrDefault();
      

      除了列检查。
      添加列检查的一种可能解决方案是使用包含参与所有表过滤的所有字段的父类,并将第二行更改为:

      var result = ((IQueryable<ParentClass>)db.Set(entity)).First(a => a.column1 == columnValue);
      

      【讨论】:

        【解决方案4】:

        如果您只有有五个表具有相同的列,并且您需要为每个表查询数据库中的该列,然后之后执行检查 不同 列的结果,然后我想我会选择 KISS 解决方案而不是使用反射。

        鉴于此示例表:

        Table1
            ColumnA, Table1ColumnB, Table1ColumnC
        
        Table2
            ColumnA, Table2ColumnB, Table2ColumnC
        
        Table3
            ColumnA, Table3ColumnB, Table3ColumnC
        

        如果不再添加表,我会像这样查询它们:

        using(var ctx = new MyDbContext())
        {
            Table1 tbl1 = ctx.Table1s.FirstOrDefault(x => x.ColumnA == "myvalue");
            Table2 tbl2 = ctx.Table2s.FirstOrDefault(x => x.ColumnA == "myvalue");
            Table3 tbl3 = ctx.Table3s.FirstOrDefault(x => x.ColumnA == "myvalue");
        
            // Perform null checks and other checks against different columns here
        } 
        

        简而言之:不要想太多:-)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-09-27
          • 1970-01-01
          • 1970-01-01
          • 2012-11-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多