实体框架 - 以编程方式将 Includes 添加到 ObjectQuery

发布于 2024-10-09 05:30:45 字数 568 浏览 0 评论 0原文

我有一个实体框架模型,其中有一个具有以下关系的用户:

User 1-* Test

每个测试都有以下关系:

Test 1-1 Course
Test 1-* TestEvent

我有一个返回用户的服务,并且在我的应用程序中的不同点我想急切地获取各种关系。我目前正在获取所有关系:

var result = (from appUser in context.AppUsers.Include("Tests.Course")
    .Include("Tests.TestEvents")
    where appUser.Login.ToLower() == loginName.ToLower() &&
    appUser.IsDeleted == false
    select appUser).FirstOrDefault();

我不想总是返回链接到测试或测试事件的课程。如何构建 ObjectQuery 并根据需要动态添加 Include 语句,而不是使用一系列 if else 语句。

I have a Entity Framework model where I have a user which has the following relationships:

User 1-* Test

Each Test has the following relationships:

Test 1-1 Course
Test 1-* TestEvent

I have a service that returns a user and at different points in my application I want to eagerly fetch various relationships. I am fetching all the relationships at present:

var result = (from appUser in context.AppUsers.Include("Tests.Course")
    .Include("Tests.TestEvents")
    where appUser.Login.ToLower() == loginName.ToLower() &&
    appUser.IsDeleted == false
    select appUser).FirstOrDefault();

I do not want to always return the Course linked to a Test or the TestEvents. How can I build an ObjectQuery and dynamically add the Include statements as required rather than having a series of if else statements.

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

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

发布评论

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

评论(1

谁对谁错谁最难过 2024-10-16 05:30:45

好吧,由于 Include 返回一个 IQueryable (LINQ 可链接),我将使用一个简单的扩展方法:

public static IQueryable<T> WithIncludes<T>(this IQueryable<T> source, string[] associations)
{
   var query = (ObjectQuery<T>)source;

   foreach (var assoc in associations)
   {
      query = query.Include(assoc);
   }
}

然后您的查询如下所示:

var inclusions = new[] { "Tests.Course", "Tests.TestEvents" };
var result = ctx.AppUsers
                .WithIncludes(inclusions)
                .Where(x => x.Login.ToLower() == loginName.ToLower())
                .Where(x => !x.IsDeleted)
                .FirstOrDefault();

要获得一些强类型考虑到 include 的其他魔术字符串性质,我为所有关联都有专门的枚举,因此我传递这些关联的 [] 并将枚举转换为字符串 include。

问题是,您的方法应该定义需要包含哪些内容。因此,您在该方法中要做的第一件事是声明需要哪些关联,然后将其传递给您的扩展方法。

这就是你的追求吗?

Well, since Include returns an IQueryable<T> (LINQ chainable), i would use a simple extension method:

public static IQueryable<T> WithIncludes<T>(this IQueryable<T> source, string[] associations)
{
   var query = (ObjectQuery<T>)source;

   foreach (var assoc in associations)
   {
      query = query.Include(assoc);
   }
}

Then your query looks like this:

var inclusions = new[] { "Tests.Course", "Tests.TestEvents" };
var result = ctx.AppUsers
                .WithIncludes(inclusions)
                .Where(x => x.Login.ToLower() == loginName.ToLower())
                .Where(x => !x.IsDeleted)
                .FirstOrDefault();

To get some strong-typing into the otherwise magic-string nature of include, i have specialized enums for all associations, so i pass an [] of those through and convert the enum to the string include.

The thing is, your methods should define what inclusions are required. So first thing you do in the method is declare what associations are required, then pass that to your extension method.

Is that what your after?

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