复杂的 Linq 查询未按预期工作

2024-04-22

我想合并 4 个表的结果并使用 LINQ 选择特定字段。 请耐心等待,因为我没有做过复杂的 LINQ 查询。

表 1 - 订阅者

表 2 - 订阅

表 3 - 状态

表 4 - 国家/地区

注意:订阅者可以有 0 个、1 个或多个订阅。 这意味着外键 (SubscriberID) 是订阅表的一部分

该查询应返回订户表中的每个订户一次。订阅者是否订阅并不重要。我需要将所有订阅者都包含在结果列表中。

这就是事情变得复杂的地方:

在结果列表中,我想包含一个属性“PubName”。此属性是一个逗号分隔的字符串,其中包含订阅者订阅的 pub 名称。 PubName 是订阅表中的一列。

我用 SQL 编写了一个存储过程,使用附加函数来构造每个订阅者的 PubName 字段。

例如:我们的列表有 3 行:

  1. 维克多,123 W 45th st #43,纽约,纽约,“Mag A、Mag B、Mag C”

(Victor 订阅了 Mag A、B 和 C)

  1. Dan,564 E 23rd st FL3,纽约,纽约,“Mag A、Mag D、Mag F”

(Dan 订阅了 Mag A、D 和 F)

  1. 妮可,78 E 12rd st #3,纽约,纽约,“NULL”

(妮可没有订阅)

    var model = await (
                from subscriber in db.Subscribers
                    // left join
                from state in db.States.Where(s => s.State_ID == subscriber.SubscriberState_ID).DefaultIfEmpty()
                    // left join
                from country in db.Countries.Where(s => s.Country_ID == subscriber.SubscriberCountry_ID).DefaultIfEmpty()                                   

                orderby subscriber.Subscriber_ID descending

                select new SubscriberGridViewModel
                {
                    Subscriber_ID = subscriber.Subscriber_ID, 
                    Pub = GetPubName(subscriber.Subscriber_ID).ToString(),                        
                    FirstName = subscriber.SubscriberFirstName,
                    LastName = subscriber.SubscriberLastName,
                    Address1 = subscriber.SubscriberAddress1,
                    Address2 = subscriber.SubscriberAddress2,
                    Email = subscriber.SubscriberEmail,
                    Organization = subscriber.SubscriberOrganizationName,
                    Phone = subscriber.SubscriberPhone,                                                
                    Zip = subscriber.SubscriberZipcode
                }).ToListAsync();

    private static string GetPubName(int? subscriber_id)
    {
        string pubs = string.Empty;

        try
        {
            var db = new CirculationEntities();

            var model = db.Subscriptions.Where(s => s.Subscriber_ID == subscriber_id).ToList();

            foreach(Subscription sub in model)
            {
                if (string.IsNullOrEmpty(pubs))
                    pubs = sub.SubscriptionPublication;
                else
                    pubs = ", " + sub.SubscriptionPublication;
            }

            return pubs;
        }
        catch
        {
            return "EMPTY";
        }                
    }

使用以下代码我收到此错误:

“LINQ to Entities 无法识别“System.String GetPubName(System.Nullable`1[System.Int32])”方法,并且此方法无法转换为存储表达式。”

我理解这个错误。方法无法转换为 LINQ 语句内的存储表达式。

  1. 在 LINQ 中可以实现这一点吗?如果是这样,有人可以告诉我怎么做吗?我无法找到解决方案。

弄清楚如何连接字符串:

var query = from subscription in db.Subscriptions.ToList()
            group subscription by subscription.Subscriber_ID into g
            select new
            {
                Subscriber_ID = g.Key,
                Pub = string.Join(", ", g.Select(x => x.SubscriptionPublication).Distinct())
            };


var model = (from s in query
             join subscriber in db.Subscribers on s.Subscriber_ID equals subscriber.Subscriber_ID
             join state in db.States on subscriber.SubscriberState_ID equals state.State_ID
             join country in db.Countries on subscriber.SubscriberCountry_ID equals country.Country_ID 
             select new SubscriberGridViewModel
             {
                 Subscriber_ID = subscriber.Subscriber_ID,
                 Pub = s.Pub,
                 FirstName = subscriber.SubscriberFirstName,
                 LastName = subscriber.SubscriberLastName,
                 Address1 = subscriber.SubscriberAddress1,
                 Address2 = subscriber.SubscriberAddress2,
                 Email = subscriber.SubscriberEmail,
                 Organization = subscriber.SubscriberOrganizationName,
                 Phone = subscriber.SubscriberPhone,
                 City = subscriber.SubscriberCity,
                 State = (subscriber.SubscriberState_ID == 54) ? subscriber.SubscriberState : state.StateName,
                 StateAbbv = (subscriber.SubscriberState_ID == 54) ? subscriber.SubscriberState : state.StateAbbreviation,
                 Country = country.CountryName,
                 Zip = subscriber.SubscriberZipcode
             }).ToList();

结果不包括未订阅的订阅者。 有什么想法如何修复它吗?


结果不包括未订阅的订阅者。

编写查询时,始终首先尝试确定根实体。您对订阅感兴趣,因此显然应该采取Subscription作为根实体。但实际上你想看看是否订户有订阅,如果有,是哪些。订阅者是根实体,因此从那里开始查询。

弄清楚如何连接字符串

Sure, db.Subscriptions.ToList()确实允许您执行 LINQ-to-objects 所存储的任何操作,但效率非常低。首先,你拉动所有Subscription数据存入内存。然后,在var model = (from s in query ...你加入DbSet每个人都拉动所有their数据存入内存。 (因为query is IEnumerable因此,不能与IQueryables 转换为一个表达式,然后转换为一个 SQL 语句)。

在 LINQ-to-Entities 查询中使用不支持的方法的策略是:查询确切的数据量——不多也不少——然后在内存中继续。

这两点都相当于这个查询:

var query = from s in db.Subcribers // root entity
    select new
    {
         Subscriber_ID = s.Subscriber_ID,
         FirstName = s.SubscriberFirstName,
         LastName = s.SubscriberLastName,
         Address1 = s.SubscriberAddress1,
         Address2 = s.SubscriberAddress2,
         Email = s.SubscriberEmail,
         Organization = s.SubscriberOrganizationName,
         Phone = s.SubscriberPhone,
         City = s.SubscriberCity,
         Zip = s.SubscriberZipcode,

         // Navigation properties here
         State = (s.SubscriberState_ID == 54) ? s.SubscriberState : s.State.StateName,
         StateAbbv = (s.SubscriberState_ID == 54) ? s.SubscriberState : s.State.StateAbbreviation,
         Country = s.Country.CountryName,

         // Empty list when no subscriptions
         Pubs = s.Subscriptions.Select(x => x.SubscriptionPublication).Distinct() 
    };
var result = query.AsEnumerable() // continue in memory
    Select(s => new SubscriberGridViewModel
             {
                 Subscriber_ID = s.Subscriber_ID,
                 FirstName = s.FirstName,
                 LastName = s.LastName,
                 Address1 = s.Address1,
                 Address2 = s.Address2,
                 Email = s.Email,
                 Organization = s.Organization,
                 Phone = s.Phone,
                 City = s.City,
                 State = s.State,
                 StateAbbv = s.StateAbbv,
                 Country = s.Country,
                 Zip = s.Zip
                 Pub = string.Join(", ", s.Pubs)
             }));

当然,如果您要查询几乎所有字段Subscriber这可能有点不那么冗长:select new { Subscriber = s, Pubs = .. }等等,但我通常会发现性能增益缩小范围与以下相比,SQL 结果集被大大低估了缩短通过过滤它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

复杂的 Linq 查询未按预期工作 的相关文章

随机推荐

  • Swift 中 CGImage 的 RGB 数据

    我尝试过培养阅读能力RGB 像素数据 https stackoverflow com questions 6073259 getting rgb pixel data from cgimage在斯威夫特 获取基本图像信息没有问题 但我认为指
  • 将系列列表传递给 SetSeries

    我将 DotNet Highcharts 与 Visual Studio 2010 结合使用 我创建了一个系列数组 List
  • {} while(0) 在宏中如何工作?

    尽管这个话题已经在本论坛和所有其他论坛上讨论过很多次 但我仍然心存疑虑 请帮忙 如何do while 0 Linux内核中的宏工作 例如 define preempt disable do while 0 它如何禁用抢占 define mi
  • 尝试使用 Razor 引擎解析模板时,程序集“mscorlib”中的“System.Security.Principal.WindowsImpersonationContext”错误

    我必须创建一个能够发送电子邮件的 Asp Net Web Api 我成功发送了电子邮件 但仅使用存储在本地变量中的简单模板 下一步是从外部文件渲染模板 如下所示 string filePath C Data EmailClient Emai
  • 远程执行hadoop作业时出现异常

    我正在尝试在远程 hadoop 集群上执行 Hadoop 作业 下面是我的代码 Configuration conf new Configuration conf set fs default name hdfs server 9000 c
  • 使用 RCurl 登录 mediawiki

    我如何使用 RCurl 或 Curl 我可以将其适应 R 包 登录到 mediawiki 我只想解析一个页面 但我需要登录 否则我无法访问它 Mediawiki API 有一个登录函数 它返回 cookie 和令牌 您必须保存并将两者发送回
  • mscordacwks.dll 和 mscorwks.dll 混淆

    mscordacwks dll 和 mscorwks dll 在 Net Framework 运行时 构建和调试过程中执行哪些不同的功能 有关于这个主题的推荐读物吗 我已经搜索了很长一段时间但失败了 提前致谢 乔治 mscorwks 是主要
  • 如何在 Node.js 中使用模板(把手或任何替代方案)而不使用框架(ex = express)?

    例如 我有这个 JSON 文档 foo json foo bar Hello World bar The End 在 Node js 中 我想使用模板 handlebars 或任何模板 从 JSON 文档生成字符串 例如 p Hello W
  • 连接 WCF 客户端缓存?

    我的应用程序使用客户端企业缓存 我想避免为每个可缓存调用编写代码 并想知道是否有一种解决方案可以缓存 WCF 客户端调用 即使对于异步调用也是如此 这可以通过 WCF 行为 或其他方式来完成吗 代码示例 前几天 我使用 WCF 服务客户端
  • JavaScript作用域问题

    我正在调用此函数 将结果分配给回调中的变量 然后记录结果 但我一直未定义 var id test getID function result id result console log id 如果我将其更改为下面的代码 那么我可以看到记录的
  • Pipenv shell 无法创建虚拟环境

    我正在尝试使用运行 Django 项目pipenv shell 但是当我输入命令时pipenv shell 它失败 pipenv shell Creating a virtualenv for this project Pipfile Us
  • 如何实现帧破坏器?

    我正在寻找一个指南 描述如何实现一个工作框架破坏者 该框架还可以处理浏览器中没有激活 JS 的人 I read 这个问题很好 https stackoverflow com questions 958997但我绝对对 自己不要这样做 或 也
  • 使用 RequireJS 时如何从 CDN 加载第三方 JavaScript?

    我一直在使用 RequireJS 进行依赖管理 并且必须说我喜欢它 JavaScript 最近确实已经成熟了 然而 我无法弄清楚的一件事是 当使用优化器将所有 JavaScript 模块捆绑到一个文件中时 如何才能继续从外部 CDN URL
  • 在 HDP 2.2 上运行 Spark Streaming 作业时出现 NoSuchMethodError

    我正在尝试在 HDP 2 2 Sandbox 上运行简单的流作业 但面临 java lang NoSuchMethodError 错误 我可以在这台机器上运行 SparkPi 示例 没有任何问题 以下是我正在使用的版本
  • 不使用 Numpy 的矩阵求逆

    我想在不使用的情况下反转矩阵numpy linalg inv 原因是我使用 Numba 来加速代码 但不支持 numpy linalg inv 所以我想知道是否可以使用 经典 Python 代码反转矩阵 With numpy linalg
  • Array.sort() 在 Firefox 和 Chrome/Edge 中的行为不同[重复]

    这个问题在这里已经有答案了 我有这段极其简化的代码 它在 Firefox 中产生的结果与您在 Chrome 或 Edge 中获得 和期望 的结果相反 尚未尝试过其他浏览器 1 2 3 4 5 sort a b gt 1 forEach a
  • 错误:(26, 13) 无法解析:com.android.support:appcompat-v7:25.0.1

    错误 26 13 无法解析 com android support appcompat v7 25 0 1错误 23 24 无法解析 com android support test espresso espresso core 2 0 这
  • grid.arrange 错误:输入必须是 grobs

    我有以下 R 脚本 library ggplot2 library gridExtra Sys setenv LANG en c1 lt ggplot mtcars aes factor cyl geom bar c2 lt ggplot
  • SwiftUI:如何在没有 AppDelegate 的情况下强制横向

    我正在制作带有视频播放器的应用程序 除了这个视频播放器之外 我的整个结构仅用于纵向视图 我想仅为该视图启用横向旋转 但我查过很多论坛 每个答案都是向 App Delegate 添加一些代码 但我没有 那我能做什么呢 这是给您的演示 您可以通
  • 复杂的 Linq 查询未按预期工作

    我想合并 4 个表的结果并使用 LINQ 选择特定字段 请耐心等待 因为我没有做过复杂的 LINQ 查询 表 1 订阅者 表 2 订阅 表 3 状态 表 4 国家 地区 注意 订阅者可以有 0 个 1 个或多个订阅 这意味着外键 Subsc