【问题标题】:EF1: Filtering derived types of entity class using .OfType<> by passing a string valueEF1:通过传递字符串值使用 .OfType<> 过滤实体类的派生类型
【发布时间】:2011-01-20 11:17:17
【问题描述】:

我尝试使用派生子类过滤 LINQ 选择。

ctx.BaseEntity.OfType&lt;SubClass&gt;() - 这很好用。

但是,我想改为使用字符串值来执行此操作。当我有很多(> 20)子类并且不使用 OfType 选择实体时,我遇到了性能障碍。我有一个从基类呈现的通用 UI,所以我不知道编译时会返回什么类类型。

所以我想做的是:

  1. 执行计划的 Select where I 只返回 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 需要 Type 而不是字符串。

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

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

【问题讨论】:

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


    【解决方案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();
    

    【讨论】:

      【解决方案2】:

      要回答有关使用字符串/运行时类型调用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 实现,所以我无法测试。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-18
        • 2019-02-25
        • 1970-01-01
        相关资源
        最近更新 更多