使用反射和泛型类型从数据库获取记录

时间:2019-03-05 11:58:06

标签: c# sql-server entity-framework

我想从数据库中检索实例。我已经使用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个表,每个表需要检查不同的列。所以我要为每个表检查列的列表

4 个答案:

答案 0 :(得分: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。但是建议是检索主键,链接的答案中也作了进一步解释。

答案 1 :(得分:1)

假设“ column1”是一个通用属性,则可以使用以下方法:

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

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

答案 2 :(得分:0)

这可能会帮助:

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

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

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

答案 3 :(得分:0)

如果情况是您具有五个具有相同列的表,则需要查询数据库中该列的每个表,然后随后执行检查不同列上的结果,那么我想我会选择一种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
} 

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