1

这是我尝试过的一堆事情......希望你能从中推断出我正在尝试做什么以及我做错了什么。好的,所以我在使用此 DoQuery 时加载相关实体时遇到问题:

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

如果我只是使用它,我最终会得到一个包含所有正确参数的对象,除了相关实体的参数......即。如果一个是引用到 User 表的 UserID,我也不会取回 User 对象。

我读到您可以执行 .Include("User") 来执行实体的 Eager Load ......但是当我尝试这个时它不起作用:

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

我还检查以确保实体集名称和模型名称是“用户”,它们是。我唯一能想到的另一件事是在其中放置多个东西,("[" + typeof(E).Name + "]")但我不确定如何在其中包含多个实体......这是我尝试过的,因为我看到有人说你可以通过放置一个 . 之间。

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

但这没有用...

如果我不在正确的轨道上,请告诉我。有谁知道在使用 ObjectContext.CreateQuery 时如何加载相关实体?任何建议或见解都会有所帮助。

谢谢,
马特

4

2 回答 2

3

CreateQuery 采用 ESQL 语句。因此,您可以编写如下内容:

public ObjectQuery<E> DoQuery(ISpecification<E> where)
{
    var esql = String.Concat(
         "SELECT VALUE e1 FROM OFTYPE(", 
         GetEntitySetName(typeof(E)),
         ", ", 
         typeof(T).FullName, 
         ") AS e1");
    return Context.CreateQuery<T>(esql).Include("User").Where(where.EvalPredicate);
}

...其中 GetEntitySetName 是您编写的一种方法,它返回您的实体类型的字符串实体集名称,或者使用预先加载策略

为什么选择 OFTYPE?如果您的模型中有继承,则此 ESQL 将返回ObjectQuery<TParent>而不是ObjectQuery<TChild>没有它。

最后,Include只有实体 E 有一个名为 User的属性时才有效。类型和实体集名称与 无关Include

于 2009-11-02T13:43:51.547 回答
1

正如克雷格在评论中指出的那样,这个答案的前一个版本是不正确的。由于我无法删除此答案(因为评论?)我至少会尝试留下一些不正确的东西。

假设您有一个包含两个实体 Product 和 ProductDetail 的模型 (.edmx)。进一步假设您要检索给定产品及其相关详细信息。

我会确保以下工作(假设您有一个 ID 为 1 且有详细记录的产品):

var result = ctx.CreateQuery<Product>("Products").Include("ProductDetails").Where(p => p.ProductId == 1);

在上面的 Include 语句中,“ProductDetails”是 Product 的一个属性。如果可行,我会尝试以下方法:

public ObjectQuery DoQuery<E>(Expression<Func<E, bool>> filter)
{
    string entitySetName = GetEntitySetName(typeof(T)); 
    return (ObjectQuery<E>)_ctx.CreateQuery<E>(entitySetName).Include("ProductDetails").Where(filter);
}

请注意,GetEntitySetName() 不是内置函数

var result = DoQuery<Product>(p => p.ProductId == 1);
于 2009-10-31T20:06:50.727 回答