【问题标题】:linq query from two database来自两个数据库的 linq 查询
【发布时间】:2019-11-06 00:06:58
【问题描述】:

我有一个来自两个数据库的 linq 查询,但是,每次程序在查询点停止。我不知道如何使用 VS 调试 linq。有人可以帮我弄清楚这里有什么问题吗?谢谢。

public List<Promotion> GetBroder(string source)
        {
            string _connString = ConfigurationManager.AppSettings["DB1"];
            PromotionDataContext dc = new PromotionDataContext(_connString);
            string connString = ConfigurationManager.AppSettings["DB2"];
            ReachDirectDataContext RDdc = new ReachDirectDataContext(connString);
            return (from b in RDdc.BrokerNos
                    from p in dc.Promotions
                    where p.Source == source && p.Broker == b.BrokerNo1
                    select new Promotion() {Code=p.Code,BrokerName=b.Name}).ToList<Promotion>();
        }

【问题讨论】:

  • 您使用的是哪种数据访问技术? (例如 EF + Linq-to-entities)

标签: c# linq entity-framework linq-to-entities


【解决方案1】:

您的 linq 语句看起来不错。为了帮助调试,我发现将 linq 查询分配给局部变量,然后返回局部变量会很有帮助。然后,您可以在 return 语句上设置断点,当调试器在断点处停止时,您可以检查查询局部变量以交互方式查看其中的内容。您可以使用 VS 中的 Locals 窗口或即时窗口在应用程序的变量中浏览,看看发生了什么。

特别是,请仔细检查 linq 查询的输入是否确实提供了数据。验证 RDdc.Brokernos 和 dc.Promotions 等是否非空。如果这些为空,则结果将为空。跟踪您的“上游”错误。

次要观点:您不需要在选择中的 .ToList() 调用上指定类型参数。编译器会自动推断类型。

【讨论】:

    【解决方案2】:

    您可以使用以下内容显示为 Linq 语句生成的 SQL。

    ReachDirectDataContext RDdc = new ReachDirectDataContext(connString);
    
    RDdc.Log = Console.Out;
    
    return (from b in RDdc.BrokerNos
            from p in dc.Promotions     
            where p.Source == source && p.Broker == b.BrokerNo1
            select new Promotion() {Code=p.Code,BrokerName=b.Name}).ToList<Promotion>();
    

    您可以尝试以下方法来分离查询。

    var promotions = from p in dc.Promotions
                     where p.Source == source
                     select p;
    
    var brokers = from o in promotions
                  join b in RDdc.BrokerNos on o.Broker equals b.BrokerNo1
                  select new Promotion 
                  {
                      Code = o.Code,
                      BrokerName = b.Name
                  };
    return brokers.ToList();
    

    【讨论】:

    • 注销时说“System.InvalidOperationException”,但我在这里没有看到任何语法错误。
    • 您能否确认您可以使用 SQL 从两个数据库中进行选择?在 SQL 中,您将在一个数据库中执行 3 部分查询(database.schema.table)。不确定Linq会做什么。您可以尝试我将在编辑中添加的内容。
    • @Leons 我尝试了您的代码,但出现错误“查询包含对在不同数据上下文中定义的项目的引用”。有什么想法吗?
    • Aaaa ... Linq 说它不喜欢查询多个数据库(至少在这种情况下不)。在这种情况下,我通常在数据库中创建一个视图,以便我的查询始终在一个数据库中,从而允许数据库建立连接。
    • 我发现了以下内容:“跨数据库行的关系完全超出了实体框架的范围”。在此链接查看更多信息social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/…
    【解决方案3】:

    对我来说,双重 from 看起来很可疑。 (这不等同于 SQL 的 JOIN 语句,如果这是您的目标的话。)

    如果可以结合上下文:

    尝试在 edmx 中创建 BrokerNos 和 Promotions 之间的关系,并在查询中使用导航属性。

    例如:

    var result = dc.Promotions.Where(p => p.Source == source).
        Select(p => new Promotion() {
            Code = p.Code,
            BrokerName = p.Broker.Name, // use new navigation property here
        });
    

    如果不是(交集将在内存中完成,而不是在 DB 上!!!:

    var result1 = dc.Promotions.Where(p => p.Source == source).
        Select(p => new Promotion() {
            Code = p.Code,
            BrokerId = p.BrokerId, // add id property for intermediate results
        }).ToList();   
    
    var result2 = RDdc.Brokers.ToList();
    
    var finalResult = result1.Where(p => result2.Contains(b => b.BrokerId == p.BrokerId)).Select(p => new Promotion{
            Code = p.Code,
            BrokerName = result2.Single(b => b.BrokerId == p.BrokerId).Name,
        });
    

    【讨论】:

    • 两个数据上下文是否都指向同一个数据库服务器实例? - 如果是这样,也许创建一个使用它们并集成它们的 edmx。然后为它打开一个上下文。见此链接:blogs.msdn.com/b/adonet/archive/2008/11/25/…
    • 必须从另一个数据库表 BrokerNo.Name 跟踪 BrokerName
    • 是的,相同的数据库服务器但不同的数据库。
    • 然后您可以运行 SQL 查询来访问它们。尝试创建一个集成 2 个独立模型的模型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    • 2011-10-29
    • 2015-07-03
    • 1970-01-01
    相关资源
    最近更新 更多