【问题标题】:How can I do an eager load when I don't know the name of the property I want to load?当我不知道要加载的属性的名称时,如何进行急切加载?
【发布时间】:2009-12-23 02:14:26
【问题描述】:

我有一个通用存储库,当我使用 DoQuery 方法从数据库中选择对象时,我需要加载一些相关实体,以免在作为外键的字段位置出现空值。

问题是存储库是通用的,所以我不知道有多少属性需要加载或它们的名称是什么(除非有某种获取它们的方法)我怎样才能使所有外键都有它们的实体已加载,同时仍保持此存储库通用?

DoQuery 方法如下:

    public ObjectQuery<E> DoQuery(ISpecification<E> where)
    {
        ObjectQuery<E> query = (ObjectQuery<E>)_ctx.CreateQuery<E>("[" + typeof(E).Name + "]").Where(where.EvalPredicate);
        return query;
    }

还有一个link to the original code for the entire repository.

我之前发布过一次,但从未得到答案,但我认为这个更相关,因为在人们假设我知道属性名称并且可以这样做之前:

.Include("PropertyNameIKnowNeedsToBeLoaded")

这是question I posted before,希望能提供一些关于我在这方面的情况的信息。

感谢任何帮助。

谢谢,
马特

【问题讨论】:

  • 您是否至少知道调用通用存储库时的关系?
  • 如果您按照规则加载所有相关属性,您可能会看到在一般情况下查询性能不佳。其影响可能很大。我通常在查询中使用投影来仅加载我需要的类型。我在这里更详细地解释了这一点:blogs.teamb.com/craigstuntz/2009/09/11/38394
  • 是的,我确实知道从我打电话的那一刻起的关系。我可以以某种方式传递它并让它以此为基础拉动它们吗?任何人的例子?

标签: asp.net-mvc entity-framework repository lazy-loading eager-loading


【解决方案1】:

您必须通过将应获取的深度传递给方法来反转控件。我对实体框架不够熟悉,不知道如何做到这一点。您可以传入一个表示提取深度的整数,该方法可以计算出如何构造与该深度相关的实体的查询。

【讨论】:

  • 谁能给我一个如何做到这一点的例子?不太确定从哪里开始尝试...
【解决方案2】:

我通过下一个方法解决了这个问题:

 public IQueryable<E> GetAll()
        {
            Type et=typeof(E);
            ObjectQuery<E> oq=_context.CreateQuery<E>("[" + typeof(E).Name + "Set]");

            foreach(System.Reflection.PropertyInfo pi in et.GetProperties())
            {
                if (pi.PropertyType.Name.Contains("EntityCollection"))
                        oq=oq.Include(pi.Name);

            }

            return oq.AsQueryable();
        }

但它的钢在北斗关系方面存在问题。所以钢铁思考这个问题

【讨论】:

    【解决方案3】:

    您可以获取类型的关系结束名称并为所有关系调用 Include。

        public ObjectQuery<E> DoQuery<E>(ISpecification<E> where) where E : new()
        {
            ObjectQuery<E> query = (ObjectQuery<E>)_ctx.CreateQuery<E>("[" + typeof(E).Name + "]").Where(where.EvalPredicate);
    
            IEntityWithRelationships entityWithRelationship = (IEntityWithRelationships)(new E());
            IEnumerable<IRelatedEnd> relatedEnds = entityWithRelationship.RelationshipManager.GetAllRelatedEnds();
            foreach (IRelatedEnd end in relatedEnds)
            {
                query= query.Include(end.TargetRoleName);
            }
    
            return query;
        }
    

    我添加了一个“新”通用约束,因为我需要从查询类型中获取 IEntityWithRelationships。我希望这会有所帮助。

    【讨论】:

    • 在“where E : new()”中为“where”提供“非泛型声明上不允许使用约束”
    • 我更正了示例 - 它必须是 DoQuery,而不仅仅是 DoQuery
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 2016-05-17
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    相关资源
    最近更新 更多