1

我有一种情况,我试图使用派生的子类过滤 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);
    

但显然这行不通,因为 OfType 需要类型而不是字符串。

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

更新: 作为原始问题的旁注,事实证明,当您投影使用导航属性的查询时 - 它也构建了怪物 SQL,所以我最终使用存储过程来填充我的 ClassType 实体基类 ID。

4

2 回答 2

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();
于 2011-01-20T11:42:31.837 回答
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 });

将此与您的存储过程结合起来以获取类名,并且您(应该?)避免大量连接 - 我没有可使用的 table-per-type 实现,所以我无法测试。

于 2014-05-29T16:46:53.540 回答