使用 ObjectContext.CreateQuery(实体框架和存储库)加载相关实体(预加载)时遇到问题

发布于 2024-08-09 18:46:08 字数 1182 浏览 13 评论 0原文

这是我尝试过的很多事情......希望您可以从中推断出我正在尝试做什么以及我做错了什么。好吧,我在使用这个 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") 来对实体进行急切加载...但当我尝试这样做时它不起作用:

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 时加载相关实体?任何建议或见解都有帮助。

谢谢,
马特

Here's a bunch of things I tried... hopefully you can extrapolate from it what I'm trying to do and what I'm doing wrong. Okay so I'm having problems with loading related entities when using this DoQuery:

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

If I just use this, I end up getting an object back that contains all proper parameters except the ones that are related entities... ie. if one is a UserID that's referenced to the User table, I do not get back the User object as well.

I read up that you can do a .Include("User") to do an Eager Load of the entity... but it doesn't work when I try this:

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

I also checked to make sure the Entity Set Name and model name are "User", which they are. The only other thing I could think of is to put multiple things in the ("[" + typeof(E).Name + "]") but I'm not sure how to include multiple entities in there... Here's what I tried since I saw someone said you could load multiple by putting a . inbetween.

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

But that didn't work...

If I'm not on the right track please let me know. Does anyone know how to load the related entities when using ObjectContext.CreateQuery? Any suggestions or insight helps.

Thanks,
Matt

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一个人的旅程 2024-08-16 18:46:08

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,而不是没有继承的 ObjectQuery

最后,仅当实体 E 具有名为 User 的属性时,Include 才起作用。类型和实体集名称与 Include 无关。

CreateQuery takes an ESQL statement. So you can write something like:

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);
}

...where GetEntitySetName is a method you write which returns the string entity set name for your entity type, or use an eager loading strategy.

Why OFTYPE? If you have inheritance in your model, this ESQL would return ObjectQuery<TParent> instead of ObjectQuery<TChild> without it.

Finally, the Include only works if the entity E has a property named User. The type and entity set name are irrelevant to Include.

°如果伤别离去 2024-08-16 18:46:08

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

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

我将确保以下工作正常进行(假设您有一个 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);

The previous rev of this answer is incorrect as pointed out by Craig in the comments. Since I can't delete this answer (because of comments?) I'll at least try to leave something that's not incorrect.

Assuming you have a model (.edmx) with two entities Product and ProductDetail. Further assuming you want to retrieve a given product and its related details.

I would make sure the following works (given you have a product with an ID of 1 that have detail records):

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

In the Include statement above, "ProductDetails" is a property on Product.
If that works, I would try the following:

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);
}

Note that GetEntitySetName() is not a built-in function

var result = DoQuery<Product>(p => p.ProductId == 1);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文