EF1:使用.OfType<>过滤派生类型的实体类通过传递一个字符串值

时间:2011-01-20 11:17:17

标签: entity-framework inheritance table-per-hierarchy table-per-type

我有一种情况,我正在尝试使用派生子类过滤LINQ选择。

ctx.BaseEntity.OfType<SubClass>() - 这很好用。

但是,我想使用字符串值来代替。当我有很多(> 20个)子类并且选择不使用OfType的实体时,我遇到了性能障碍,这不是一个选项。我有一个从基类渲染的通用UI,所以我不知道在编译时会返回什么类类型。

所以我想做的是:

  1. 执行投射选择我所在的位置 从中返回SubClassType 数据库
  2. 执行第二次选择 使用此值作为OfType 只选择相关的相关内容 来自数据库的实体(无质量 工会生成)

        int id = 1;
        var classType = (from c in ctx.BaseClass.Include("ClassType")
                                   where c.id == id
                                   select new
                                              {
                                                  c.ClassType.TypeName
                                              }).First();
    
        BaseClass caseQuery = ctx.BaseClass.OfType<classType.TypeName>()
                        .Include("ClassType")
                        .Include("ChildEntity1")
                        .Include("ChildEntity2")
                        .Where(x => x.id== id);
    
  3. 但显然这不起作用,因为OfType需要Type而不是字符串。

    关于如何实现这一目标的任何想法?

    更新 作为原始问题的旁注,事实证明,在您投影使用导航属性的查询的那一刻 - 它也构建了怪物SQL,所以我最终使用存储过程从BaseClass填充我的ClassType实体同上

2 个答案:

答案 0 :(得分:1)

所以我刚刚使用eSQL工作,我之前从未使用过它。我已经在这里发布了代码,以防万一它可以帮到某人。还有其他人有他们能想到的更强类型的解决方案吗?

BaseClass caseQuery = ctx.BaseClass.CreateQuery<BaseClass>("SELECT VALUE c FROM OFTYPE(Entities.[BaseClass],namespace.[" + classType.TypeName + "])  as c")
                .Include("ClassType")
                .Include("ChildEntity1")
                .Include("ChildEntity2")
                .Where(x => x.id== id).FirstOrDefault();

答案 1 :(得分:0)

要回答有关使用字符串/运行时类型调用OfType的标题问题,您可以执行以下操作:

// Get the type, assuming the derived type is defined in the same assembly 
// as the base class and you have the type name as a string
var typeToFilter = typeof(BaseClass)
     .Assembly
     .GetType("Namespace." + derivedTypeName);

// The use reflection to get the OfType method and call it directly
MethodInfo ofType = typeof(Queryable).GetMethod("OfType");
MethodInfo ofTypeGeneric = method.MakeGenericMethod(new Type[] { typeToFilter });
var result = (IQueryable<Equipment>)generic.Invoke(null, new object[] { equipment });

将此与您的存储过程相结合以获取类名称,您(应该?)避免大规模加入 - 我没有使用每个类型的表实现,因此我无法测试。